library(tidyverse)
library(Rlab)
library(BSDA)
#Discrete ##UNIFORM ###Population ####1. Model
m_ <- 1
n <- 7
range <- m_:n
mean <- (n+m_)/2
variance <- ((n-m_)*(n-m_+2))/12
print(str_c("m = ", m_, ", n = ", n, ", mean = ", mean, ", variance = ", variance))
[1] "m = 1, n = 7, mean = 4, variance = 4"
rdunif(10, n, m_)
[1] 4 1 7 1 2 6 4 6 6 1
dunif <- tibble(x = range, d = 1/(n-m_+1), p = (x-m_+1)/(n-m_+1),
xd = x*d)
dunif
ggplot(dunif) + geom_point(aes(x = x, y = p))

ggplot(dunif) + geom_point(aes(x = x, y = d))

##BERNOULLI ###Population ####1. Model
#Parameters
p <- 0.001 #right-skew for p <0.5, symmetric for p = 0.5, left-skew for p >0.5
str_c("p = ", p)
[1] "p = 0.001"
p_2 <- 0.8
#Range
range <- 0:1
#p.m.f.
dber <- function(x, p){
p^x*(1-p)^(1-x) #special case of binomial, where n_ = 1
}
bernoulli <- tibble(x = range,
d = dber(x, p),
p = pbern(x, p))
bernoulli
ggplot(bernoulli) + geom_point(aes(x = x, y = p))

ggplot(bernoulli) + geom_point(aes(x = x, y = d))

####2. Expected values
mu <- p
sigma_squared <- p*(1-p)
sigma <- sqrt(sigma_squared)
# x <- bernoulli$x
# m <- bernoulli$m
#mu <- sum(x*m)
#sigma_squared <- sum((x-mu)^2*m)
#sigma_squared <- sum(x^2*m)-mu^2
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", round(sigma,2))
[1] "mu = 0.001, sigma_squared = 0.000999, sigma = 0.03"
####3. Sampling distribution of the sample mean, expected values
#range: 0-1
n <- 5000
exp_X_bar <- mu #p
var_X_bar <- sigma_squared/n #p(1-p)/n
sd_X_bar <- sqrt(var_X_bar) #sqrt(p(1-p)/n)
#if X ~ binom(n,p), E(X) = np, V(X) = np(1-p)
# E(X/n) = E(X)/n = p
# V(X/n) = V(X)/n^2 = np(1-p)/n^2 = p(1-p)/n
# S(X/n) = sqrt(p(1-p)/n)
# X/n ≈ N(p, p(1-p)/n), when both np and n(1-p) ≥ 5
str_c("n = ", n, ", exp_X_bar = ", exp_X_bar, ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3), ", n*p = ", n*p, ", n*(1-p) = ", n*(1-p))
[1] "n = 5000, exp_X_bar = 0.001, var_X_bar = 0, sd_X_bar = 0, n*p = 5, n*(1-p) = 4995"
###Sample
x <- rbern(n, p) #a single observation of binomial random variable is n observations of a Bernoulli random variable
n_2 <- 60
x_2 <- rbern(n_2, p_2)
####a. Estimates
sample_mean <- mean(x) #p_hat, sample_total/n, (binomial x/n)
sample_total <- sum(x) #(x binomial)
est_var_X_bar <- (sample_mean*(1-sample_mean))/n #estimate sigma squared with sample_mean
est_sd_X_bar <- sqrt((sample_mean*(1-sample_mean))/n)
sample_mean_2 <- mean(x_2)
est_var_X_bar_2 <- (sample_mean_2*(1-sample_mean_2))/n_2 #estimate sigma squared with sample_mean
ext_var_X_bar_diff <- est_var_X_bar + est_var_X_bar_2
est_sd_X_bar_diff <- sqrt(ext_var_X_bar_diff)
sample_mean_diff <- sample_mean-sample_mean_2
#Sample variance notes
# sample_var <- sample_mean*(1-sample_mean) #p_hat(1-p_hat), biased estimator of S_squared?
# sample_sd <- sqrt(sample_var)
# sample_var2 <- var(x) #sample variance
# sample_sd2 <- sqrt(sample_var)
# sample_var3 <- sum((x-mean(x))^2)/length(x) #same as 1, biased?
# sample_sd3 <- sqrt(sample_var3)
str_c("sample_total = ", sample_total, ", sample_mean = ", sample_mean, ", est_var_X_bar = ", round(est_var_X_bar, 3), ", est_sd_X_bar = ", round(est_sd_X_bar, 3))
[1] "sample_total = 2, sample_mean = 4e-04, est_var_X_bar = 0, est_sd_X_bar = 0"
####b. Likelhood
#MLE:
bernoullin_mle <- tibble(theta = seq(0,1,0.001),
m = dbinom(sum(x), n, p = theta)) #single observation of binomial
ggplot(bernoullin_mle) + geom_line(aes(x = theta, y = m))

####c.i. Confidence interval
alpha <- 0.05
#Confidence interval
CI <- c(sample_mean - qnorm(1-alpha/2)*est_sd_X_bar,
sample_mean + qnorm(1-alpha/2)*est_sd_X_bar)
str_c("sample_mean = ", sample_mean, ", CI = ", paste(round(CI,3), collapse = ", "))
[1] "sample_mean = 4e-04, CI = 0, 0.001"
####c.ii. Confidence interval difference of proportions
CI <- c(sample_mean_diff - qnorm(1-alpha/2)*est_sd_X_bar_diff,
sample_mean_diff + qnorm(1-alpha/2)*est_sd_X_bar_diff)
str_c("sample_mean_diff = ", round(sample_mean_diff,3), ", CI = ", paste(round(CI,3), collapse = ", "))
[1] "sample_mean_diff = -0.666, CI = -0.786, -0.547"
####d. Hypothesis test
alpha <- 0.05
p_0 = 0.3
critical_values <- c(p_0 - qnorm(1-alpha/2)*(sqrt(p_0*(1-p_0)/n)),
p_0 + qnorm(1-alpha/2)*(sqrt(p_0*(1-p_0)/n))) #not p_hat?
z <- ((sample_mean-p_0))/(sqrt(p_0*(1-p_0)/n))
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))
str_c("H0: p_0 = ", p_0)
[1] "H0: p_0 = 0.3"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 0.287, 0.313"
str_c("sample_mean = ", round(sample_mean,3))
[1] "sample_mean = 0"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = -46.229"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0"
prop.test(sample_total, n, p_0, correct = FALSE) #CI slightly different??
1-sample proportions test without continuity correction
data: sample_total out of n, null probability p_0
X-squared = 2137.1, df = 1, p-value < 2.2e-16
alternative hypothesis: true p is not equal to 0.3
95 percent confidence interval:
0.0001097013 0.0014573865
sample estimates:
p
4e-04
##BINOMIAL ###Population ####1. Model
#number of successes in a sequence of n independent Bernoulli trials with probability p
n_ <- 3000 #finite range, Bernoulli if n = 1
p <- 12/3000
# p <- l/n_
#right-skew for p <0.5, symmetric for p = 0.5, left-skew for p >0.5
#The Poisson distribution is the limiting distribution of X ~ B(n, l/n)
#If n is large and p is small (n ≥ 50 and p ≤ 0.05) then the binomial random variable B(n,p) has approximately the same distribution as Poisson(np)
# range <- 0:n_
range <- 0:50
db <- function(x, n_, p){
choose(n_, x)*p^x*(1-p)^(n_-x)
}
binom <- tibble(x = range,
d = db(x, n_, p), #one mode, can take any value, depends on p
p = pbinom(x, n_, p))
binom
ggplot(binom) + geom_point(aes(x = x, y = p))

ggplot(binom) + geom_point(aes(x = x, y = d))

####2. Expected values
x <- binom$x
d <- binom$d
mu <- n_*p #linear, ranges from 0 < mean < n
#mu <- sum(x*m)
sigma_squared <- n_*p*(1-p) #quadratic, max 0.25n, var -> mean as p -> 0, mean - var -> n as p -> 1
#sigma_squared <- sum((x-mu)^2*m)
#sigma_squared <- sum(x^2*m)-mu^2
sigma <- sqrt(sigma_squared)
str_c("mu (np) = ", mu, ", sigma_squared (np(1-p)) = ", sigma_squared, ", sigma = ", round(sigma,2))
[1] "mu (np) = 12, sigma_squared (np(1-p)) = 11.952, sigma = 3.46"
####3. Sampling distributions of the sample mean, expected values
n <- 50
exp_X_bar <- mu
var_X_bar <- sigma_squared/n #p*(1-p) (same as sigma_squared Bernoulli)
sd_X_bar <- sqrt(var_X_bar)
str_c("n = ", n, ", exp_X_bar = ", exp_X_bar, ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3))
[1] "n = 50, exp_X_bar = 12, var_X_bar = 0.239, sd_X_bar = 0.489"
##POISSON ###Population ####1. Model
#The Poisson distribution is the limiting distribution of X ~ B(n, l/n)
#If n is large and p is small (n ≥ 50 and p ≤ 0.05) then the binomial random variable B(n,p) has approximately the same distribution as Poisson(np)
#For a Poisson process in which events occur at random at rate l, the number of events that occur during a time interval of length t has a Poisson distribution with parameter lt
l <- 0.1 #constant event rate
t <- 100 #time interval
lt <- l*t #decreasing p.m.f. when lt < 1
str_c("rate = ", l, ", time = ", t, ", lt = ", lt)
[1] "rate = 0.1, time = 100, lt = 10"
#Range
range <- 0:50 #unbounded to the right
#p.d.f
dp <- function(x, lt){
(exp(1)^(-lt)*lt^x)/factorial(x)
}
poisson <- tibble(x = range,
d = dp(x, lt), #one mode, can take any value
p = ppois(x, lt))
poisson
ggplot(poisson) + geom_point(aes(x = x, y = p))

ggplot(poisson) + geom_point(aes(x = x, y = d))

####2. Expected values
#Mu, sigma
mu <- lt
sigma_squared <- lt
sigma <- sqrt(sigma_squared)
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", round(sigma,3))
[1] "mu = 10, sigma_squared = 10, sigma = 3.162"
####3. Sampling distribution of the sample mean, expected values
n <- 1000
exp_X_bar <- mu
var_X_bar <- sigma_squared/n
sd_X_bar <- sqrt(var_X_bar)
str_c("n = ", n, ", exp_X_bar = ", exp_X_bar, ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3))
[1] "n = 1000, exp_X_bar = 10, var_X_bar = 0.01, sd_X_bar = 0.1"
[1] “n = 1000, exp_X_bar = 0.1, var_X_bar = 0, sd_X_bar = 0.01”
[1] “n = 100, exp_X_bar = 1, var_X_bar = 0.01, sd_X_bar = 0.1”
[1] “n = 10, exp_X_bar = 10, var_X_bar = 1, sd_X_bar = 1”
###Sample
x <- rpois(n, lt)
# O <- c(21,8,6,1)
# n <- sum(O)
# range <- 0:(length(O)-1)
# x <- rep(range, O)
#E.coli
#x <- c(3274,3198,3258,3276,3456,3384,3280,3081,3062,3023,3073,2794,3068)
####a. Estimates
str_c("lt = ", lt) #can use normal approximation when lt >= 30
[1] "lt = 10"
sample_mean <- mean(x) #l_hat
est_var_X_bar <- sample_mean/n #estimate sigma squared with sample_mean
est_sd_X_bar <- sqrt(sample_mean/n)
str_c("sample_mean (l_hat) = ", round(sample_mean,3), ", est_var_X_bar = ", round(est_var_X_bar,3), ", est_sd_X_bar = ", round(est_sd_X_bar,3))
[1] "sample_mean (l_hat) = 10.081, est_var_X_bar = 0.01, est_sd_X_bar = 0.1"
####b. Likelhood
theta <- seq(0,max(range), max(range)/1000)
lp <- function(x, theta){
n <- length(x)
c <- 1/prod(factorial(x))
sample_mean <- mean(x)
c*exp(1)^(-n*theta)*theta^(n*sample_mean)
}
poisson_mle <- tibble(theta = theta, m = lp(x, theta))
ggplot(poisson_mle) + geom_line(aes(x = theta, y = m))

####c. Confidence interval
alpha <- 0.05
str_c("alpha = ", alpha)
[1] "alpha = 0.05"
#Confidence interval
CI <- c(sample_mean - qnorm(1-alpha/2)*est_sd_X_bar,
sample_mean + qnorm(1-alpha/2)*est_sd_X_bar)
str_c("CI = ", paste(round(CI,3), collapse = ", "))
[1] "CI = 9.884, 10.278"
“CI = 0.059, 0.093” CI*100 = 5.9 9.3
“CI = 0.732, 1.108” CI*10 = 7.32 11.08
“CI = 6.693, 10.307”
##GEOMETRIC ###Population ####1. Model
p <- 0.8
str_c("p = ", p)
[1] "p = 0.8"
range <- 1:10 #1,2,3,..., unbounded to the right
#p.m.f.
dg <- function(x, p){
((1-p)^(x-1))*p
}
#c.d.f.
pg <- function(x, p){
1-(1-p)^x
}
geom <- tibble(x = range,
d = dg(x, p), #decreasing p.m.f., mode always at 1
p = pg(x, p))
geom
ggplot(geom) + geom_point(aes(x = x, y = p))

ggplot(geom) + geom_point(aes(x = x, y = d))

####2. Expected values
#Mu, sigma
mu <- 1/p #mean < variance for p < 0.5, mean > variance for p > 0.5
sigma_squared <- (1-p)/p^2
sigma <- sqrt(sigma_squared)
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", sigma)
[1] "mu = 1.25, sigma_squared = 0.3125, sigma = 0.559016994374947"
###Sample
x <- rgeom(100, p) + 1 #shifted geometric distribution
####a. Estimates
sample_mean <- mean(x)
p_hat <- 1/sample_mean #biased
str_c('sample_mean = ', round(sample_mean,2), ", p_hat = ", round(p_hat,2))
[1] "sample_mean = 1.25, p_hat = 0.8"
####b. Likelhood
theta <- seq(0,1,0.001)
lg <- function(x, theta){
n <- length(x)
(1-theta)^(sum(x)-n)*theta^n
}
geom_mle <- tibble(theta = theta, m = lg(x, theta))
ggplot(geom_mle) + geom_line(aes(x = theta, y = m))

##NEGATIVE BINOMIAL ###Population ####1. Model
r <- 5
p <- 0.5
str_c("p = ", p, ", r = ", r)
[1] "p = 0.5, r = 5"
range <- 0:50 #1,2,3,..., unbounded to the right
#p.m.f.
#c.d.f.
nb <- tibble(x = range,
d = dnbinom(x, r, p),
p = pnbinom(x, r, p))
nb
ggplot(nb) + geom_point(aes(x = x, y = p))

ggplot(nb) + geom_point(aes(x = x, y = d))

#Continuous ##UNIFORM ###Population ####1. Model
a <- 1
b <- 5
mean <- (a+b)/2
variance <- (b-a)^2/12
range <- c(a,b)
print(str_c("a = ", a, ", b = ", b, ", mean = ", mean, ", variance = ", variance))
[1] "a = 1, b = 5, mean = 3, variance = 1.33333333333333"
unif <- tibble(x = range, d = 1/(b-a), p = (x-a)/(b-a))
unif
ggplot(unif) + geom_line(aes(x = x, y = p))

ggplot(unif) + geom_line(aes(x = x, y = d))

###Sample
x <- runif(10, a, b)
##EXPONENTIAL ###Population ####1. Model
#For a Poisson process win which events occur at random at rate l, the waiting time between successive events has an exponential distribution with parameter l
#Parameters
l <- 1/26 #rate
range <- seq(0.0001, 100, 100/1000) # X > 0, unbounded to the right
str_c("lambda = ", l)
[1] "lambda = 0.0384615384615385"
#p.d.f.
de <- function(x, l){
l*exp(1)^(-l*x) #decreasing p.d.f.
}
#c.d.f.
pe <- function(x, l){
p = 1-exp(1)^(-l*x)
}
exponential <- tibble(x = range,
d = de(x, l),
p = pe(x, l))
exponential
ggplot(exponential) + geom_line(aes(x = x, y = p))

ggplot(exponential) + geom_line(aes(x = x, y = d))

####2. Expected values
#Mu, sigma
mu <- 1/l
sigma_squared <- 1/l^2
sigma <- sqrt(sigma_squared) #mu = sigma
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", sigma)
[1] "mu = 26, sigma_squared = 676, sigma = 26"
###Sample
x <- rexp(10, l)
####a. Estimates
sample_mean <- mean(x)
l_hat = 1/sample_mean #biased
####b. Likelhood
theta <- seq(0,3*l, 3*l/1000)
str_c('sample_mean = ', round(sample_mean,2), ", l_hat = ", round(l_hat,2))
[1] "sample_mean = 10.28, l_hat = 0.1"
le <- function(x, theta){
n <- length(x)
sample_mean <- mean(x)
(theta^n)*exp(1)^(-theta*n*sample_mean)
}
exponential_mle <- tibble(theta = theta, m = le(x, theta))
ggplot(exponential_mle) + geom_line(aes(x = theta, y = m))

##NORMAL ###Population ####1. Model
#Parameters
mu <- 7
sigma_squared <- 100
sigma <- sqrt(sigma_squared)
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", sigma)
[1] "mu = 7, sigma_squared = 100, sigma = 10"
mu_2 <- 9
#Range
range <- seq(mu-4*sigma, mu+4*sigma, sigma/12) #unbounded
#p.d.f.
dn <- function(x, mu, sigma){
(1/(sigma*sqrt(2*pi)))*exp(-0.5*((x-mu)/sigma)^2)
}
normal <- tibble(x = range,
d = dn(x, mu, sigma), #symmetric about mean
p = pnorm(x, mu, sigma))
normal
ggplot(normal) + geom_line(aes(x = x, y = p))

ggplot(normal) + geom_line(aes(x = x, y = d))

####2. Expected values
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", round(sigma,3))
[1] "mu = 7, sigma_squared = 100, sigma = 10"
####3. Sampling distributions of the sample mean, expected values
n <- 20
exp_X_bar <- mu
var_X_bar <- sigma_squared/n
sd_X_bar <- sigma/sqrt(n)
str_c("n = ", n, ", exp_X_bar = ", round(exp_X_bar,3), ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3))
[1] "n = 20, exp_X_bar = 7, var_X_bar = 5, sd_X_bar = 2.236"
####4. Sampling distribution of the sample variance, expected
values
exp_S_squared <- sigma_squared
exp_S <- sigma
str_c("exp_S_squared = ", round(exp_S_squared,3), ", exp_S = ", round(exp_S,3))
[1] "exp_S_squared = 100, exp_S = 10"
###Sample
x <- rnorm(n, mu, sigma)
n_2 <- 30
x_2 <- rnorm(n, mu_2, sigma)
# x <- c(-6,1,2,4,24,27,33)
# n <- length(x)
####a. Estimates
sample_mean <- mean(x) #mu_hat
sample_var <- var(x) #s_squared
sample_sd <- sqrt(sample_var) #s
sample_mean_2 <- mean(x_2)
sample_var_2 <- var(x_2)
sample_var_pooled <- ((n-1)*sample_var+(n_2-1)*sample_var_2)/(n+n_2-2)
sample_sd_pooled <- sqrt(sample_var_pooled)
sample_mean_diff <- sample_mean-sample_mean_2
# sigma_squared_hat <- sum((x-mean(x))^2)/length(x) #biased
# sigma_hat <- sqrt(sum((x-mean(x))^2)/length(x)) #biased
est_var_X_bar <- sample_var/n #estimate sigma_squared with sample_var
est_sd_X_bar <- sample_sd/sqrt(n) #estimate sigma with sample_sd
str_c("sample_mean = ", round(sample_mean,3), ", sample_var = ", round(sample_var,3), ", sample_sd = ", round(sample_sd,3), ", est_var_X_bar = ", round(est_var_X_bar,3), ", est_sd_X_bar = ", round(est_sd_X_bar,3))
[1] "sample_mean = 7.621, sample_var = 93.561, sample_sd = 9.673, est_var_X_bar = 4.678, est_sd_X_bar = 2.163"
####c. Confidence interval
alpha <- 0.05
str_c("alpha = ", alpha)
[1] "alpha = 0.05"
#Confidence interval
CI <- c(sample_mean - qnorm(1-alpha/2)*est_sd_X_bar,
sample_mean + qnorm(1-alpha/2)*est_sd_X_bar)
str_c("CI = ", paste(round(CI,3), collapse = ", "))
[1] "CI = 3.382, 11.86"
####d. Hypothesis test
mu_0 = 7
critical_values <- c(mu_0 - qnorm(1-alpha/2)*est_sd_X_bar,
mu_0 + qnorm(1-alpha/2)*est_sd_X_bar)
z <- (sample_mean-mu_0)/est_sd_X_bar #when H_0 is true, Z ~ N(0,1)
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))
str_c("H0: mu_0 = ", mu_0)
[1] "H0: mu_0 = 7"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 2.761, 11.239"
str_c("sample_mean = ", round(sample_mean,3))
[1] "sample_mean = 7.621"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = 0.287"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.77409"
z.test(x, mu = mu_0, sigma.x = sample_sd)
One-sample z-Test
data: x
z = 0.28703, p-value = 0.7741
alternative hypothesis: true mean is not equal to 7
95 percent confidence interval:
3.381649 11.859978
sample estimates:
mean of x
7.620813
####e. Power and sample size
#When H_1 is true, mu = mu_0 + d, Z - d/sd_X_bar ~ N(0,1)
d <- 2
sigma <- 5
n <- 30
sd_X_bar <- sigma/sqrt(n)
alpha <- 0.05
d_z <- d/sd_X_bar
power <- 1 - pnorm(qnorm(1-alpha/2) - d_z)
str_c("d = ", d, ", d_z = ", round(d_z,3), ", power = ", round(power,4))
[1] "d = 2, d_z = 2.191, power = 0.5913"
####f. Sample size
gamma <- 0.9
sample_size <- (sigma_squared/d^2)*(qnorm(1-alpha/2) - qnorm(1-gamma))^2
str_c("d = ", d, ", gamma = ", gamma, ", sample size = ", ceiling(sample_size))
[1] "d = 2, gamma = 0.9, sample size = 263"
##STUDENT’S T ###Population ####1. Model
nu <- n-1
range <- seq(-4, 4, 0.08) #unbounded
print(str_c("df = ", nu))
[1] "df = 29"
rt(10, nu)
[1] -1.3197317 0.3084248 -0.7673561 -1.7364395 -0.3621944 2.1136429 1.9471722
[8] -0.6259278 0.2380963 0.1272593
t <- tibble(x = range,
d = dt(x, nu),
p = pt(x, nu))
t
ggplot(t) + geom_line(aes(x = x, y = p))

ggplot(t) + geom_line(aes(x = x, y = d))

###Sample Use normal
####c.i. Confidence interval
alpha <- 0.05
str_c("alpha = ", alpha)
[1] "alpha = 0.05"
#Confidence interval
CI <- c(sample_mean - qt(1-alpha/2, nu)*est_sd_X_bar,
sample_mean + qt(1-alpha/2, nu)*est_sd_X_bar)
str_c("CI = ", paste(round(CI,6), collapse = ", "))
[1] "CI = 3.197229, 12.044397"
####c.ii Confidence interval for difference of means
nu_2 <- n + n_2 - 2
CI <- c(sample_mean_diff - qt(1-alpha/2, nu_2)*sample_sd_pooled*sqrt(1/n+1/n_2),
sample_mean_diff + qt(1-alpha/2, nu_2)*sample_sd_pooled*sqrt(1/n+1/n_2))
str_c("CI = ", paste(round(CI,6), collapse = ", "))
[1] "CI = -11.381151, -1.090367"
####d. Hypothesis test
mu_0 = 0
critical_values <- c(mu_0 - qt(1-alpha/2, nu)*est_sd_X_bar,
mu_0 + qt(1-alpha/2, nu)*est_sd_X_bar)
t <- (sample_mean-mu_0)/est_sd_X_bar
standard_critical_values <- c(qt(alpha/2, nu), qt(1-alpha/2, nu))
p_value <- 2*(1-pt(abs(t), nu))
str_c("H0: mu_0 = ", mu_0)
[1] "H0: mu_0 = 0"
str_c("df = ", length(x)-1)
[1] "df = 19"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = -4.424, 4.424"
str_c("sample_mean = ", round(sample_mean,3))
[1] "sample_mean = 7.621"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -2.045, 2.045"
str_c("t = ", round(t, 4))
[1] "t = 3.5235"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.00143"
t.test(x, mu = mu_0, sigma.x = sample_sd)
One Sample t-test
data: x
t = 3.5235, df = 19, p-value = 0.002271
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
3.093856 12.147771
sample estimates:
mean of x
7.620813
##CHI-SQUARED
r <- 6
range <- seq(0.0001, 5*r, r/20) #x > 0
print(str_c("degrees of freedom = ", r, ", mean = ", r, ", variance = ", 2*r))
[1] "degrees of freedom = 6, mean = 6, variance = 12"
rchisq(10, r)
[1] 4.429201 6.033584 9.319503 4.932174 6.542898 3.467198 1.571303 5.914670
[9] 9.338379 9.020098
chisq <- tibble(x = range,
d = dchisq(x, r),
p = pchisq(x, r))
chisq
ggplot(chisq) + geom_line(aes(x = x, y = p))

ggplot(chisq) + geom_line(aes(x = x, y = d))

###Goodness of fit ####discrete uniform
m_ <- 1
n <- 7
O <- c(17,10,12,15,5,4,8)
n <- sum(O)
x <- 1:length(O)
m <- 1/(n-m_+1)
gof <- tibble(x = x,
m = m,
O = O,
E = m*n,
'(O-E)^2/E' = (O-E)^2/E)
gof
x2 <- sum(gof$`(O-E)^2/E`)
n_parameters <- 0
r <- nrow(gof) - n_parameters - 1 #k - p - 1
str_c("n = ", n, ", chi_square = ", round(x2,3), ", p = ", round(1-pchisq(x2, r),3))
[1] "n = 71, chi_square = 728, p = 0"
####geometric
p_hat <- 0.657
O <- c(71,28,10)
n <- sum(O)
x <- 1:(length(O)-1)
y <- str_c("≥", (length(O)))
m <- c(dg(x, p_hat),1-pg(max(x), p_hat))
gof <- tibble(x = c(x,y),
m = m,
O = O,
E = m*n,
'(O-E)^2/E' = (O-E)^2/E)
gof
x2 <- sum(gof$`(O-E)^2/E`)
n_parameters <- 1
r <- nrow(gof) - n_parameters - 1 #k - p - 1
str_c("n = ", n, ", p_hat = ", p_hat, ", df = ", r, " , chi_square = ", round(x2,3), ", p = ", round(1-pchisq(x2, r),3))
[1] "n = 109, p_hat = 0.657, df = 1 , chi_square = 1.108, p = 0.293"
####Poisson
l_hat <- 0.7
O <- c(144,91,32,13)
n <- sum(O)
x <- 0:(length(O)-2)
y <- str_c("≥", (length(O)-1))
m <- c(dpois(x, l_hat),1-ppois(max(x), l_hat))
gof <- tibble(x = c(x,y),
m = m,
O = O,
E = m*n,
'(O-E)^2/E' = (O-E)^2/E)
gof
x2 <- sum(gof$`(O-E)^2/E`)
n_parameters <- 1 #estimated from data
r <- nrow(gof) - n_parameters - 1 #k - p - 1
str_c("n = ", n, ", l_hat = ", l_hat, ", df = ", r, ", chi_square = ", round(x2,3), ", p = ", round(1-pchisq(x2, r),3))
[1] "n = 280, l_hat = 0.7, df = 2, chi_square = 1.952, p = 0.377"
##REGRESSION ###Population
#Parameters
sigma_squared <- 150
sigma <- sqrt(sigma_squared)
alpha_ <- 5
beta <- 4
x <- seq(-5,20,0.25)
h <- function(x, alpha_, beta){
alpha_ + beta*x
}
#p.d.f.
regression_model <- tibble(x = x,
q_0.025 = qnorm(0.025, h(x, alpha_, beta), sigma),
q_0.5 = qnorm(0.5, h(x, alpha_, beta), sigma),
q_0.975 = qnorm(0.975, h(x, alpha_, beta), sigma)
) %>%
gather(key = quantile, value = z, -x)
regression_model
ggplot(regression_model) + geom_line(aes(x = x, y = z, col = quantile))

####Sampling distribution of the estimators, expected values
n <- 50
exp_alpha_hat <- alpha
exp_beta_hat <- beta
###Sample
regression_sample <- tibble(x = runif(n, min(x), max(x)),
y = rnorm(x, h(x, alpha_, beta), sigma))
ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + expand_limits(x = 0, y = 0)

####a. Estimates
x <- regression_sample$x
x_bar <- mean(x)
y <- regression_sample$y
S_xx <- sum((x-mean(x))^2)
S_yy <- sum((y-mean(y))^2)
S_xy <- sum((x-mean(x))*(y-mean(y)))
#Least squares estimates of parameters
beta_hat <- S_xy/S_xx
#est_var_beta_hat <- sigma_squared/S_xx
alpha_hat <- mean(y) - beta_hat*mean(x)
#est_var_alpha_hat <- x_bar^2/S_xx+1/n
#Best fit
best_fit <- function(x, alpha_hat, beta_hat){
alpha_hat + beta_hat*x
}
regression_sample <- regression_sample %>%
mutate(y_hat = best_fit(x, alpha_hat, beta_hat),
residual = y-y_hat )
#Variance of residuals
y_hat <- regression_sample$y_hat
sum_squared_diff_y_hat <- sum((y-y_hat)^2)
s_squared <- sum_squared_diff_y_hat/(n-2) #unbiased estimator of sigma_squared, the variance of the random terms
s <- sqrt(s_squared)
est_sd_beta_hat <- s/sqrt(S_xx)
ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + geom_line(aes(x = x, y = y_hat))

####c.i. Confidence interval for beta
alpha <- 0.05
CI_beta <- c(
beta_hat - qt(1-alpha/2, n-2)*est_sd_beta_hat,
beta_hat + qt(1-alpha/2, n-2)*est_sd_beta_hat)
str_c("beta_hat = ", round(beta_hat,3), ", CI_beta = ", paste(round(CI_beta,3), collapse = ", "))
[1] "beta_hat = 3.799, CI_beta = 3.345, 4.253"
####c.ii. Confidence interval for mean response
est_sd_Y_bar <- function(x, s, x_bar, S_xx, n){
s*sqrt((x-x_bar)^2/S_xx + 1/n)
}
regression_sample <- regression_sample %>%
mutate(CI_low = y_hat - qt(1-alpha/2, n-2)*est_sd_Y_bar(x, s, x_bar, S_xx, n),
CI_high = y_hat + qt(1-alpha/2, n-2)*est_sd_Y_bar(x, s, x_bar, S_xx, n))
ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + geom_line(aes(x = x, y = y_hat)) + geom_line(aes(x = x, y = CI_low)) + geom_line(aes(x = x, y = CI_high))

####c.iii. Prediction interval
est_sd_Y <- function(x, s, x_bar, S_xx, n){
s*sqrt((x-x_bar)^2/S_xx + 1/n + 1)
}
regression_sample <- regression_sample %>%
mutate(CI_low = y_hat - qt(1-alpha/2, n-2)*est_sd_Y(x, s, x_bar, S_xx, n),
CI_high = y_hat + qt(1-alpha/2, n-2)*est_sd_Y(x, s, x_bar, S_xx, n))
ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + geom_line(aes(x = x, y = y_hat)) + geom_line(aes(x = x, y = CI_low)) + geom_line(aes(x = x, y = CI_high))

####d. Hypothesis test for beta
beta_0 = 0
critical_values <- c(beta_0 - qt(1-alpha/2, n-2)*est_sd_beta_hat,
beta_0 + qt(1-alpha/2, n-2)*est_sd_beta_hat)
t <- (beta_hat-beta_0)/est_sd_beta_hat
standard_critical_values <- c(qt(alpha/2, n-2), qt(1-alpha/2, n-2))
p_value <- 2*(1-pt(abs(t), n-2))
##NON-PARAMETRIC ###Wilkoxon signed rank
#Single sample
x <- c(19, 35, 36, 28, 37, 10, 25, 34, 30, 39)
m_0 = 35 #set hypothesized median
d_ <- x-m_0 #calculate difference
#set of paired differences
x1 <- c(171, 729, 679, 431, 300, 310, 794, 970, 388)
x2 <- c(198, 734, 779, 776, 300, 750, 697, 368, 488)
d_ <- x1-x2
d <- d_[d_!=0] #remove zeros
rank <- rank(abs(d)) #find the rank of absolute values
w_plus <- sum(rank[sign(d)==1]) #sum of the ranks of positive differences
w_plus
[1] 11
wilcox.test(d)
Wilcoxon signed rank test with continuity correction
data: d
V = 11, p-value = 0.3621
alternative hypothesis: true location is not equal to 0
Normal approximation
#normal approximation when n ≥ 16
n <- length(d)
exp_w_plus <- (n*(n+1))/4
var_w_plus <- (n*(n+1)*(2*n+1))/24
sd_w_plus <- sqrt(var_w_plus)
alpha <- 0.05
critical_values <- c(m_0 - qnorm(1-alpha/2)*sd_w_plus,
m_0 + qnorm(1-alpha/2)*sd_w_plus)
z <- (w_plus - exp_w_plus)/sd_w_plus
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))
str_c("n = ", n)
[1] "n = 8"
str_c("H0: m_0 = ", m_0)
[1] "H0: m_0 = 35"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 21.003, 48.997"
str_c("exp_w_plus = ", exp_w_plus)
[1] "exp_w_plus = 18"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = -0.98"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.32699"
###Mann-Whitney
a = c(101,104,107,107,121,121,124,134,146)
b = c(91,93,97,100,101,102,107,114,115,126,131)
u_a <- sum(rank(c(a,b))[1:length(a)])
u_a
[1] 117.5
Normal approximation
#normal approximation when each sample ≥ 8
n_a <- length(a)
n_b <- length(b)
exp_u_a <- (n_a*(n_a+n_b+1))/2
var_u_a <- (n_a*n_b*(n_a+n_b+1))/12
sd_u_a <- sqrt(var_u_a)
alpha <- 0.05
critical_values <- c(m_0 - qnorm(1-alpha/2)*sd_u_a,
m_0 + qnorm(1-alpha/2)*sd_u_a)
z <- (u_a - exp_u_a)/sd_u_a
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))
str_c("n_a = ", n_a, ", n_b = ", n_b)
[1] "n_a = 9, n_b = 11"
str_c("H0: m_0 = ", m_0)
[1] "H0: m_0 = 35"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 9.202, 60.798"
str_c("exp_u_a = ", exp_u_a)
[1] "exp_u_a = 94.5"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = 1.747"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.08057"
##NOTES ##To do Non-linear regression models and transformations
Chi-square goodness of fit test for binomial
###Normal probability plot
O <- c(33, 2, 24, 27, 4, 1, -6)
x <- sort(O)
n <- length(x)
i <- 1:n
p <- i/(n+1)
y <- qnorm(p)
qplot(x,y) + geom_smooth(method = "lm", se = FALSE)

###Central limit theorem
#n <- 10
n_trials <- 500
x <- c()
for (i in 1:n_trials) {
x[i] <- mean(rbernoulli(n_trials,0.001))
}
#ggplot() + stat_qq_line(aes(sample = x)) + stat_qq(aes(sample = x))
ggplot() + geom_histogram(aes(x = x), binwidth = 0.00002)

###Ladder of powers
df <- tibble(x = rnorm(10, 100, 10), y = x + rnorm(10, 0, 1))
df
ggplot(df) + geom_point(aes(x = x, y = y))

###Binomial vs Poisson
x <- binom %>% select(x, Binomial = d)
y <- poisson %>% select(x, Poisson = d) %>% left_join(x, by = "x")
z <- y %>% gather(key, value = d, -x)
ggplot(z) + geom_point(aes(x = x, y = d, col = key))

###Statistical tables
x <- 0:9/100
phi_table <- tibble(z = seq(0,4,0.1),
'0' = round(pnorm(z+x[1]),4),
'1' = round(pnorm(z+x[2]),4),
'2' = round(pnorm(z+x[3]),4),
'3' = round(pnorm(z+x[4]),4),
'4' = round(pnorm(z+x[5]),4),
'5' = round(pnorm(z+x[6]),4),
'6' = round(pnorm(z+x[7]),4),
'7' = round(pnorm(z+x[8]),4),
'8' = round(pnorm(z+x[9]),4),
'9' = round(pnorm(z+x[10]),4)
)
phi_table
qz_table <- tibble(a = seq(0.5,0.999,0.01), q_a = round(qnorm(a),3))
qz_table
qt_table <- tibble(df = 1:100,
'0.90' = round(qt(0.9, df),3),
'0.95' = round(qt(0.95, df),3),
'0.975' = round(qt(0.975, df),3),
'0.99' = round(qt(0.99, df),3),
'0.995' = round(qt(0.995, df),3),
'0.999' = round(qt(0.999, df),3))
qt_table
chisq_table <- tibble(df = 1:100,
'0.005' = round(qchisq(0.005, df),2),
'0.01' = round(qchisq(0.01, df),2),
'0.025' = round(qchisq(0.025, df),2),
'0.05' = round(qchisq(0.05, df),2),
'0.1' = round(qchisq(0.1, df),2),
'0.5' = round(qchisq(0.5, df),2),
'0.9' = round(qchisq(0.9, df),2),
'0.95' = round(qchisq(0.95, df),2),
'0.975' = round(qchisq(0.975, df),2),
'0.99' = round(qchisq(0.99, df),2),
'0.995' = round(qchisq(0.995, df),2))
chisq_table
Poisson vs geometric
p <- 0.7
l <- 0.5 #generally steeper than geometric, gets a bump as approaches l = 1
df <- tibble(x = 0:9, Geometric = round(dgeom(x, p), 4), Poisson = round(dpois(x, l), 4)) %>% gather(key, value, -x)
ggplot(df) + geom_point(aes(x = x, y = value, col = key))

Binomial alternative MLE?
# MLE multiple observations
# x <- rbinom(10, n, p)
# x
# theta <- seq(0,1,0.001)
# m <- NULL
# for(i in 1:length(theta)){
# m[i] <- prod(d(x, n, theta[i]))
# }
# binom_mle2 <- tibble(theta = theta, m = m)
# MLE2 <- filter(binom_mle2, m == max(m))$theta
# print(str_c("MLE2 = ", MLE2))
# mean(rand)/n
# ggplot(binom_mle2) + geom_line(aes(x = theta, y = m))
LS0tCnRpdGxlOiAiRGlzdHJpYnV0aW9ucyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoUmxhYikKbGlicmFyeShCU0RBKQpgYGAKCiNEaXNjcmV0ZQojI1VOSUZPUk0KIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQptXyA8LSAxCm4gPC0gNwpyYW5nZSA8LSBtXzpuCm1lYW4gPC0gKG4rbV8pLzIKdmFyaWFuY2UgPC0gKChuLW1fKSoobi1tXysyKSkvMTIKcHJpbnQoc3RyX2MoIm0gPSAiLCBtXywgIiwgbiA9ICIsIG4sICIsIG1lYW4gPSAiLCBtZWFuLCAiLCB2YXJpYW5jZSA9ICIsIHZhcmlhbmNlKSkKcmR1bmlmKDEwLCBuLCBtXykKZHVuaWYgPC0gdGliYmxlKHggPSByYW5nZSwgZCA9IDEvKG4tbV8rMSksIHAgPSAoeC1tXysxKS8obi1tXysxKSwKICAgICAgICAgICAgICAgIHhkID0geCpkKQpkdW5pZgpnZ3Bsb3QoZHVuaWYpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSBwKSkKZ2dwbG90KGR1bmlmKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojI0JFUk5PVUxMSQojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9CiNQYXJhbWV0ZXJzCnAgPC0gMC4wMDEgI3JpZ2h0LXNrZXcgZm9yIHAgPDAuNSwgc3ltbWV0cmljIGZvciBwID0gMC41LCBsZWZ0LXNrZXcgZm9yIHAgPjAuNQpzdHJfYygicCA9ICIsIHApCgpwXzIgPC0gMC44CgojUmFuZ2UKcmFuZ2UgPC0gMDoxCiNwLm0uZi4KZGJlciA8LSBmdW5jdGlvbih4LCBwKXsKICAgICAgICBwXngqKDEtcCleKDEteCkgICNzcGVjaWFsIGNhc2Ugb2YgYmlub21pYWwsIHdoZXJlIG5fID0gMQp9CmJlcm5vdWxsaSA8LSB0aWJibGUoeCA9IHJhbmdlLAogICAgICAgICAgICAgICAgZCA9IGRiZXIoeCwgcCksCiAgICAgICAgICAgICAgICBwID0gcGJlcm4oeCwgcCkpCmJlcm5vdWxsaQpnZ3Bsb3QoYmVybm91bGxpKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChiZXJub3VsbGkpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSBkKSkKYGBgCiMjIyMyLiBFeHBlY3RlZCB2YWx1ZXMKYGBge3J9Cm11IDwtIHAKc2lnbWFfc3F1YXJlZCA8LSBwKigxLXApCnNpZ21hIDwtIHNxcnQoc2lnbWFfc3F1YXJlZCkKCiMgeCA8LSBiZXJub3VsbGkkeAojIG0gPC0gYmVybm91bGxpJG0KI211IDwtIHN1bSh4Km0pCiNzaWdtYV9zcXVhcmVkIDwtIHN1bSgoeC1tdSleMiptKQojc2lnbWFfc3F1YXJlZCA8LSBzdW0oeF4yKm0pLW11XjIgCgpzdHJfYygibXUgPSAiLCBtdSwgIiwgc2lnbWFfc3F1YXJlZCA9ICIsIHNpZ21hX3NxdWFyZWQsICIsIHNpZ21hID0gIiwgcm91bmQoc2lnbWEsMikpCmBgYAojIyMjMy4gU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiwgZXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojcmFuZ2U6IDAtMQpuIDwtIDUwMDAKZXhwX1hfYmFyIDwtIG11ICNwCnZhcl9YX2JhciA8LSBzaWdtYV9zcXVhcmVkL24gI3AoMS1wKS9uCnNkX1hfYmFyIDwtIHNxcnQodmFyX1hfYmFyKSAjc3FydChwKDEtcCkvbikKICAgICAgICAKI2lmIFggfiBiaW5vbShuLHApLCBFKFgpID0gbnAsIFYoWCkgPSBucCgxLXApCiMgRShYL24pID0gRShYKS9uID0gcAojIFYoWC9uKSA9IFYoWCkvbl4yID0gbnAoMS1wKS9uXjIgPSBwKDEtcCkvbgojIFMoWC9uKSA9IHNxcnQocCgxLXApL24pCiMgWC9uIOKJiCBOKHAsIHAoMS1wKS9uKSwgd2hlbiBib3RoIG5wIGFuZCBuKDEtcCkg4omlIDUKCnN0cl9jKCJuID0gIiwgbiwgIiwgZXhwX1hfYmFyID0gIiwgZXhwX1hfYmFyLCAiLCB2YXJfWF9iYXIgPSAiLCByb3VuZCh2YXJfWF9iYXIsMyksICIsIHNkX1hfYmFyID0gIiwgcm91bmQoc2RfWF9iYXIsMyksICIsIG4qcCA9ICIsIG4qcCwgICIsIG4qKDEtcCkgPSAiLCBuKigxLXApKQpgYGAKIyMjU2FtcGxlCmBgYHtyfQp4IDwtIHJiZXJuKG4sIHApICNhIHNpbmdsZSBvYnNlcnZhdGlvbiBvZiBiaW5vbWlhbCByYW5kb20gdmFyaWFibGUgaXMgbiBvYnNlcnZhdGlvbnMgb2YgYSBCZXJub3VsbGkgcmFuZG9tIHZhcmlhYmxlCm5fMiA8LSA2MAp4XzIgPC0gcmJlcm4obl8yLCBwXzIpCmBgYAojIyMjYS4gRXN0aW1hdGVzCmBgYHtyfQpzYW1wbGVfbWVhbiA8LSBtZWFuKHgpICNwX2hhdCwgc2FtcGxlX3RvdGFsL24sIChiaW5vbWlhbCB4L24pCnNhbXBsZV90b3RhbCA8LSBzdW0oeCkgIyh4IGJpbm9taWFsKQplc3RfdmFyX1hfYmFyIDwtIChzYW1wbGVfbWVhbiooMS1zYW1wbGVfbWVhbikpL24gI2VzdGltYXRlIHNpZ21hIHNxdWFyZWQgd2l0aCBzYW1wbGVfbWVhbgplc3Rfc2RfWF9iYXIgPC0gc3FydCgoc2FtcGxlX21lYW4qKDEtc2FtcGxlX21lYW4pKS9uKQoKc2FtcGxlX21lYW5fMiA8LSBtZWFuKHhfMikKZXN0X3Zhcl9YX2Jhcl8yIDwtIChzYW1wbGVfbWVhbl8yKigxLXNhbXBsZV9tZWFuXzIpKS9uXzIgI2VzdGltYXRlIHNpZ21hIHNxdWFyZWQgd2l0aCBzYW1wbGVfbWVhbgpleHRfdmFyX1hfYmFyX2RpZmYgPC0gZXN0X3Zhcl9YX2JhciArIGVzdF92YXJfWF9iYXJfMgplc3Rfc2RfWF9iYXJfZGlmZiA8LSBzcXJ0KGV4dF92YXJfWF9iYXJfZGlmZikKc2FtcGxlX21lYW5fZGlmZiA8LSBzYW1wbGVfbWVhbi1zYW1wbGVfbWVhbl8yCgojU2FtcGxlIHZhcmlhbmNlIG5vdGVzCiMgc2FtcGxlX3ZhciA8LSBzYW1wbGVfbWVhbiooMS1zYW1wbGVfbWVhbikgI3BfaGF0KDEtcF9oYXQpLCBiaWFzZWQgZXN0aW1hdG9yIG9mIFNfc3F1YXJlZD8KIyBzYW1wbGVfc2QgPC0gc3FydChzYW1wbGVfdmFyKQojIHNhbXBsZV92YXIyIDwtIHZhcih4KSAjc2FtcGxlIHZhcmlhbmNlCiMgc2FtcGxlX3NkMiA8LSBzcXJ0KHNhbXBsZV92YXIpCiMgc2FtcGxlX3ZhcjMgPC0gc3VtKCh4LW1lYW4oeCkpXjIpL2xlbmd0aCh4KSAjc2FtZSBhcyAxLCBiaWFzZWQ/CiMgc2FtcGxlX3NkMyA8LSBzcXJ0KHNhbXBsZV92YXIzKQoKc3RyX2MoInNhbXBsZV90b3RhbCA9ICIsIHNhbXBsZV90b3RhbCwgIiwgc2FtcGxlX21lYW4gPSAiLCBzYW1wbGVfbWVhbiwgIiwgZXN0X3Zhcl9YX2JhciA9ICIsIHJvdW5kKGVzdF92YXJfWF9iYXIsIDMpLCAiLCBlc3Rfc2RfWF9iYXIgPSAiLCByb3VuZChlc3Rfc2RfWF9iYXIsIDMpKQpgYGAKIyMjI2IuIExpa2VsaG9vZApgYGB7cn0KI01MRTogCmJlcm5vdWxsaW5fbWxlIDwtIHRpYmJsZSh0aGV0YSA9IHNlcSgwLDEsMC4wMDEpLAogICAgICAgICAgICAgICAgICAgIG0gPSBkYmlub20oc3VtKHgpLCBuLCBwID0gdGhldGEpKSAjc2luZ2xlIG9ic2VydmF0aW9uIG9mIGJpbm9taWFsCmdncGxvdChiZXJub3VsbGluX21sZSkgKyBnZW9tX2xpbmUoYWVzKHggPSB0aGV0YSwgeSA9IG0pKQpgYGAKIyMjI2MuaS4gQ29uZmlkZW5jZSBpbnRlcnZhbApgYGB7cn0KYWxwaGEgPC0gMC4wNQoKI0NvbmZpZGVuY2UgaW50ZXJ2YWwKQ0kgPC0gYyhzYW1wbGVfbWVhbiAtIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyLCAKICAgICAgICBzYW1wbGVfbWVhbiArIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyKQpzdHJfYygic2FtcGxlX21lYW4gPSAiLCBzYW1wbGVfbWVhbiwgIiwgQ0kgPSAiLCBwYXN0ZShyb3VuZChDSSwzKSwgY29sbGFwc2UgPSAiLCAiKSkKYGBgCiMjIyNjLmlpLiBDb25maWRlbmNlIGludGVydmFsIGRpZmZlcmVuY2Ugb2YgcHJvcG9ydGlvbnMKYGBge3J9CkNJIDwtIGMoc2FtcGxlX21lYW5fZGlmZiAtIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyX2RpZmYsIAogICAgICAgIHNhbXBsZV9tZWFuX2RpZmYgKyBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2Jhcl9kaWZmKQpzdHJfYygic2FtcGxlX21lYW5fZGlmZiA9ICIsIHJvdW5kKHNhbXBsZV9tZWFuX2RpZmYsMyksICIsIENJID0gIiwgcGFzdGUocm91bmQoQ0ksMyksIGNvbGxhcHNlID0gIiwgIikpCmBgYAoKIyMjI2QuIEh5cG90aGVzaXMgdGVzdApgYGB7cn0KYWxwaGEgPC0gMC4wNQpwXzAgPSAwLjMKY3JpdGljYWxfdmFsdWVzIDwtIGMocF8wIC0gcW5vcm0oMS1hbHBoYS8yKSooc3FydChwXzAqKDEtcF8wKS9uKSksCiAgICAgICAgICAgICAgICAgICAgIHBfMCArIHFub3JtKDEtYWxwaGEvMikqKHNxcnQocF8wKigxLXBfMCkvbikpKSAjbm90IHBfaGF0Pwp6IDwtICgoc2FtcGxlX21lYW4tcF8wKSkvKHNxcnQocF8wKigxLXBfMCkvbikpCnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHFub3JtKGFscGhhLzIpLCBxbm9ybSgxLWFscGhhLzIpKQoKcF92YWx1ZSA8LSAyKigxLXBub3JtKGFicyh6KSkpCnN0cl9jKCJIMDogcF8wID0gIiwgcF8wKQpzdHJfYygiY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJzYW1wbGVfbWVhbiA9ICIsIHJvdW5kKHNhbXBsZV9tZWFuLDMpKQpzdHJfYygic3RhbmRhcmQgY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoc3RhbmRhcmRfY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJ6ID0gIiwgcm91bmQoeiwgMykpCnN0cl9jKCJwX3ZhbHVlID0gIiwgcm91bmQocF92YWx1ZSwgNSkpCgpwcm9wLnRlc3Qoc2FtcGxlX3RvdGFsLCBuLCBwXzAsIGNvcnJlY3QgPSBGQUxTRSkgI0NJIHNsaWdodGx5IGRpZmZlcmVudD8/CmBgYAojI0JJTk9NSUFMCiMjI1BvcHVsYXRpb24gCiMjIyMxLiBNb2RlbApgYGB7cn0KI251bWJlciBvZiBzdWNjZXNzZXMgaW4gYSBzZXF1ZW5jZSBvZiBuIGluZGVwZW5kZW50IEJlcm5vdWxsaSB0cmlhbHMgd2l0aCBwcm9iYWJpbGl0eSBwCm5fIDwtIDMwMDAgI2Zpbml0ZSByYW5nZSwgQmVybm91bGxpIGlmIG4gPSAxCnAgPC0gMTIvMzAwMAojIHAgPC0gbC9uXyAKI3JpZ2h0LXNrZXcgZm9yIHAgPDAuNSwgc3ltbWV0cmljIGZvciBwID0gMC41LCBsZWZ0LXNrZXcgZm9yIHAgPjAuNQojVGhlIFBvaXNzb24gZGlzdHJpYnV0aW9uIGlzIHRoZSBsaW1pdGluZyBkaXN0cmlidXRpb24gb2YgWCB+IEIobiwgbC9uKQojSWYgbiBpcyBsYXJnZSBhbmQgcCBpcyBzbWFsbCAobiDiiaUgNTAgYW5kIHAg4omkIDAuMDUpIHRoZW4gdGhlIGJpbm9taWFsIHJhbmRvbSB2YXJpYWJsZSBCKG4scCkgaGFzIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZGlzdHJpYnV0aW9uIGFzIFBvaXNzb24obnApCgojIHJhbmdlIDwtIDA6bl8KcmFuZ2UgPC0gMDo1MAoKZGIgPC0gZnVuY3Rpb24oeCwgbl8sIHApewogICAgICAgIGNob29zZShuXywgeCkqcF54KigxLXApXihuXy14KQp9CmJpbm9tIDwtIHRpYmJsZSh4ID0gcmFuZ2UsCiAgICAgICAgICAgICAgICBkID0gZGIoeCwgbl8sIHApLCAjb25lIG1vZGUsIGNhbiB0YWtlIGFueSB2YWx1ZSwgZGVwZW5kcyBvbiBwCiAgICAgICAgICAgICAgICBwID0gcGJpbm9tKHgsIG5fLCBwKSkKYmlub20KZ2dwbG90KGJpbm9tKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChiaW5vbSkgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKIyMjIzIuIEV4cGVjdGVkIHZhbHVlcwpgYGB7cn0KeCA8LSBiaW5vbSR4CmQgPC0gYmlub20kZAptdSA8LSBuXypwICNsaW5lYXIsIHJhbmdlcyBmcm9tIDAgPCBtZWFuIDwgbgojbXUgPC0gc3VtKHgqbSkKc2lnbWFfc3F1YXJlZCA8LSBuXypwKigxLXApICNxdWFkcmF0aWMsIG1heCAwLjI1biwgdmFyIC0+IG1lYW4gYXMgcCAtPiAwLCBtZWFuIC0gdmFyIC0+IG4gYXMgcCAtPiAxCiNzaWdtYV9zcXVhcmVkIDwtIHN1bSgoeC1tdSleMiptKQojc2lnbWFfc3F1YXJlZCA8LSBzdW0oeF4yKm0pLW11XjIgCnNpZ21hIDwtIHNxcnQoc2lnbWFfc3F1YXJlZCkKc3RyX2MoIm11IChucCkgPSAiLCBtdSwgIiwgc2lnbWFfc3F1YXJlZCAobnAoMS1wKSkgPSAiLCBzaWdtYV9zcXVhcmVkLCAiLCBzaWdtYSA9ICIsIHJvdW5kKHNpZ21hLDIpKQpgYGAKIyMjIzMuIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIHNhbXBsZSBtZWFuLCBleHBlY3RlZCB2YWx1ZXMKYGBge3J9Cm4gPC0gNTAKZXhwX1hfYmFyIDwtIG11CnZhcl9YX2JhciA8LSBzaWdtYV9zcXVhcmVkL24gI3AqKDEtcCkgKHNhbWUgYXMgc2lnbWFfc3F1YXJlZCBCZXJub3VsbGkpCnNkX1hfYmFyIDwtIHNxcnQodmFyX1hfYmFyKQoKc3RyX2MoIm4gPSAiLCBuLCAiLCBleHBfWF9iYXIgPSAiLCBleHBfWF9iYXIsICIsIHZhcl9YX2JhciA9ICIsIHJvdW5kKHZhcl9YX2JhciwzKSwgIiwgc2RfWF9iYXIgPSAiLCByb3VuZChzZF9YX2JhciwzKSkKYGBgCiMjUE9JU1NPTgojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9CiNUaGUgUG9pc3NvbiBkaXN0cmlidXRpb24gaXMgdGhlIGxpbWl0aW5nIGRpc3RyaWJ1dGlvbiBvZiBYIH4gQihuLCBsL24pCiNJZiBuIGlzIGxhcmdlIGFuZCBwIGlzIHNtYWxsIChuIOKJpSA1MCBhbmQgcCDiiaQgMC4wNSkgdGhlbiB0aGUgYmlub21pYWwgcmFuZG9tIHZhcmlhYmxlIEIobixwKSBoYXMgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBkaXN0cmlidXRpb24gYXMgUG9pc3NvbihucCkKI0ZvciBhIFBvaXNzb24gcHJvY2VzcyBpbiB3aGljaCBldmVudHMgb2NjdXIgYXQgcmFuZG9tIGF0IHJhdGUgbCwgdGhlIG51bWJlciBvZiBldmVudHMgdGhhdCBvY2N1ciBkdXJpbmcgYSB0aW1lIGludGVydmFsIG9mIGxlbmd0aCB0IGhhcyBhIFBvaXNzb24gZGlzdHJpYnV0aW9uIHdpdGggcGFyYW1ldGVyIGx0CmwgPC0gMC4xICNjb25zdGFudCBldmVudCByYXRlCnQgPC0gMTAwICN0aW1lIGludGVydmFsCmx0IDwtIGwqdCAjZGVjcmVhc2luZyBwLm0uZi4gd2hlbiBsdCA8IDEKc3RyX2MoInJhdGUgPSAiLCBsLCAiLCB0aW1lID0gIiwgdCwgIiwgbHQgPSAiLCBsdCkKI1JhbmdlCnJhbmdlIDwtIDA6NTAgI3VuYm91bmRlZCB0byB0aGUgcmlnaHQKI3AuZC5mCmRwIDwtIGZ1bmN0aW9uKHgsIGx0KXsKICAgICAgICAoZXhwKDEpXigtbHQpKmx0XngpL2ZhY3RvcmlhbCh4KQp9CnBvaXNzb24gPC0gdGliYmxlKHggPSByYW5nZSwKICAgICAgICAgICAgICAgIGQgPSBkcCh4LCBsdCksICNvbmUgbW9kZSwgY2FuIHRha2UgYW55IHZhbHVlCiAgICAgICAgICAgICAgICBwID0gcHBvaXMoeCwgbHQpKQpwb2lzc29uCmdncGxvdChwb2lzc29uKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChwb2lzc29uKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyMjMi4gRXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojTXUsIHNpZ21hCm11IDwtIGx0CnNpZ21hX3NxdWFyZWQgPC0gbHQKc2lnbWEgPC0gc3FydChzaWdtYV9zcXVhcmVkKQoKc3RyX2MoIm11ID0gIiwgbXUsICIsIHNpZ21hX3NxdWFyZWQgPSAiLCBzaWdtYV9zcXVhcmVkLCAiLCBzaWdtYSA9ICIsIHJvdW5kKHNpZ21hLDMpKQpgYGAKIyMjIzMuIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4sIGV4cGVjdGVkIHZhbHVlcwpgYGB7cn0KbiA8LSAxMDAwCmV4cF9YX2JhciA8LSBtdQp2YXJfWF9iYXIgPC0gc2lnbWFfc3F1YXJlZC9uCnNkX1hfYmFyIDwtIHNxcnQodmFyX1hfYmFyKQpzdHJfYygibiA9ICIsIG4sICIsIGV4cF9YX2JhciA9ICIsIGV4cF9YX2JhciwgIiwgdmFyX1hfYmFyID0gIiwgcm91bmQodmFyX1hfYmFyLDMpLCAiLCBzZF9YX2JhciA9ICIsIHJvdW5kKHNkX1hfYmFyLDMpKQpgYGAKWzFdICJuID0gMTAwMCwgZXhwX1hfYmFyID0gMC4xLCB2YXJfWF9iYXIgPSAwLCBzZF9YX2JhciA9IDAuMDEiCgpbMV0gIm4gPSAxMDAsIGV4cF9YX2JhciA9IDEsIHZhcl9YX2JhciA9IDAuMDEsIHNkX1hfYmFyID0gMC4xIgoKWzFdICJuID0gMTAsIGV4cF9YX2JhciA9IDEwLCB2YXJfWF9iYXIgPSAxLCBzZF9YX2JhciA9IDEiCgoKIyMjU2FtcGxlCmBgYHtyfQp4IDwtIHJwb2lzKG4sIGx0KQoKIyBPIDwtIGMoMjEsOCw2LDEpCiMgbiA8LSBzdW0oTykKIyByYW5nZSA8LSAwOihsZW5ndGgoTyktMSkKIyB4IDwtIHJlcChyYW5nZSwgTykKCiNFLmNvbGkKI3ggPC0gYygzMjc0LDMxOTgsMzI1OCwzMjc2LDM0NTYsMzM4NCwzMjgwLDMwODEsMzA2MiwzMDIzLDMwNzMsMjc5NCwzMDY4KQpgYGAKIyMjI2EuIEVzdGltYXRlcwpgYGB7cn0Kc3RyX2MoImx0ID0gIiwgbHQpICNjYW4gdXNlIG5vcm1hbCBhcHByb3hpbWF0aW9uIHdoZW4gbHQgPj0gMzAKCnNhbXBsZV9tZWFuIDwtIG1lYW4oeCkgI2xfaGF0Cgplc3RfdmFyX1hfYmFyIDwtIHNhbXBsZV9tZWFuL24gI2VzdGltYXRlIHNpZ21hIHNxdWFyZWQgd2l0aCBzYW1wbGVfbWVhbgplc3Rfc2RfWF9iYXIgPC0gc3FydChzYW1wbGVfbWVhbi9uKQoKc3RyX2MoInNhbXBsZV9tZWFuIChsX2hhdCkgPSAiLCByb3VuZChzYW1wbGVfbWVhbiwzKSwgIiwgZXN0X3Zhcl9YX2JhciA9ICIsIHJvdW5kKGVzdF92YXJfWF9iYXIsMyksICIsIGVzdF9zZF9YX2JhciA9ICIsIHJvdW5kKGVzdF9zZF9YX2JhciwzKSkKYGBgCiMjIyNiLiBMaWtlbGhvb2QKYGBge3J9CnRoZXRhIDwtIHNlcSgwLG1heChyYW5nZSksIG1heChyYW5nZSkvMTAwMCkKbHAgPC0gZnVuY3Rpb24oeCwgdGhldGEpewogICAgICAgIG4gPC0gbGVuZ3RoKHgpCiAgICAgICAgYyA8LSAxL3Byb2QoZmFjdG9yaWFsKHgpKQogICAgICAgIHNhbXBsZV9tZWFuIDwtIG1lYW4oeCkKICAgICAgICBjKmV4cCgxKV4oLW4qdGhldGEpKnRoZXRhXihuKnNhbXBsZV9tZWFuKQp9CnBvaXNzb25fbWxlIDwtIHRpYmJsZSh0aGV0YSA9IHRoZXRhLCBtID0gbHAoeCwgdGhldGEpKQpnZ3Bsb3QocG9pc3Nvbl9tbGUpICsgZ2VvbV9saW5lKGFlcyh4ID0gdGhldGEsIHkgPSBtKSkKYGBgCiMjIyNjLiBDb25maWRlbmNlIGludGVydmFsCmBgYHtyfQphbHBoYSA8LSAwLjA1CnN0cl9jKCJhbHBoYSA9ICIsIGFscGhhKQoKI0NvbmZpZGVuY2UgaW50ZXJ2YWwKQ0kgPC0gYyhzYW1wbGVfbWVhbiAtIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyLCAKICAgICAgICBzYW1wbGVfbWVhbiArIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyKQpzdHJfYygiQ0kgPSAiLCBwYXN0ZShyb3VuZChDSSwzKSwgY29sbGFwc2UgPSAiLCAiKSkKYGBgCiJDSSA9IDAuMDU5LCAwLjA5MyIKQ0kqMTAwID0gNS45IDkuMwoKIkNJID0gMC43MzIsIDEuMTA4IgpDSSoxMCA9IDcuMzIgMTEuMDgKCiJDSSA9IDYuNjkzLCAxMC4zMDciCgoKIyNHRU9NRVRSSUMKIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQpwIDwtIDAuOApzdHJfYygicCA9ICIsIHApCnJhbmdlIDwtIDE6MTAgIzEsMiwzLC4uLiwgdW5ib3VuZGVkIHRvIHRoZSByaWdodAojcC5tLmYuCmRnIDwtIGZ1bmN0aW9uKHgsIHApewogICAgICAgICgoMS1wKV4oeC0xKSkqcAp9CiNjLmQuZi4KcGcgPC0gZnVuY3Rpb24oeCwgcCl7CiAgICAgICAgMS0oMS1wKV54Cn0KZ2VvbSA8LSB0aWJibGUoeCA9IHJhbmdlLCAKICAgICAgICAgICAgICAgIGQgPSBkZyh4LCBwKSwgI2RlY3JlYXNpbmcgcC5tLmYuLCBtb2RlIGFsd2F5cyBhdCAxIAogICAgICAgICAgICAgICAgcCA9IHBnKHgsIHApKQpnZW9tCmdncGxvdChnZW9tKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChnZW9tKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyMjMi4gRXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojTXUsIHNpZ21hCm11IDwtIDEvcCAjbWVhbiA8IHZhcmlhbmNlIGZvciBwIDwgMC41LCBtZWFuID4gdmFyaWFuY2UgZm9yIHAgPiAwLjUKc2lnbWFfc3F1YXJlZCA8LSAoMS1wKS9wXjIKc2lnbWEgPC0gc3FydChzaWdtYV9zcXVhcmVkKQpzdHJfYygibXUgPSAiLCBtdSwgIiwgc2lnbWFfc3F1YXJlZCA9ICIsIHNpZ21hX3NxdWFyZWQsICIsIHNpZ21hID0gIiwgc2lnbWEpCmBgYAojIyNTYW1wbGUKYGBge3J9CnggPC0gcmdlb20oMTAwLCBwKSArIDEgI3NoaWZ0ZWQgZ2VvbWV0cmljIGRpc3RyaWJ1dGlvbgpgYGAKIyMjI2EuIEVzdGltYXRlcwpgYGB7cn0Kc2FtcGxlX21lYW4gPC0gbWVhbih4KQpwX2hhdCA8LSAxL3NhbXBsZV9tZWFuICNiaWFzZWQKCnN0cl9jKCdzYW1wbGVfbWVhbiA9ICcsIHJvdW5kKHNhbXBsZV9tZWFuLDIpLCAiLCBwX2hhdCA9ICIsIHJvdW5kKHBfaGF0LDIpKQpgYGAKIyMjI2IuIExpa2VsaG9vZApgYGB7cn0KdGhldGEgPC0gc2VxKDAsMSwwLjAwMSkKbGcgPC0gZnVuY3Rpb24oeCwgdGhldGEpewogICAgICAgIG4gPC0gbGVuZ3RoKHgpCiAgICAgICAgKDEtdGhldGEpXihzdW0oeCktbikqdGhldGFebgp9Cmdlb21fbWxlIDwtIHRpYmJsZSh0aGV0YSA9IHRoZXRhLCBtID0gbGcoeCwgdGhldGEpKQpnZ3Bsb3QoZ2VvbV9tbGUpICsgZ2VvbV9saW5lKGFlcyh4ID0gdGhldGEsIHkgPSBtKSkKYGBgCiMjTkVHQVRJVkUgQklOT01JQUwKIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQpyIDwtIDUKcCA8LSAwLjUKc3RyX2MoInAgPSAiLCBwLCAiLCByID0gIiwgcikKcmFuZ2UgPC0gMDo1MCAjMSwyLDMsLi4uLCB1bmJvdW5kZWQgdG8gdGhlIHJpZ2h0CiNwLm0uZi4KI2MuZC5mLgoKbmIgPC0gdGliYmxlKHggPSByYW5nZSwgCiAgICAgICAgICAgICAgICBkID0gZG5iaW5vbSh4LCByLCBwKSwgCiAgICAgICAgICAgICAgICBwID0gcG5iaW5vbSh4LCByLCBwKSkKbmIKZ2dwbG90KG5iKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChuYikgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKCiNDb250aW51b3VzCiMjVU5JRk9STQojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9CmEgPC0gMQpiIDwtIDUKbWVhbiA8LSAoYStiKS8yCnZhcmlhbmNlIDwtIChiLWEpXjIvMTIKcmFuZ2UgPC0gYyhhLGIpCnByaW50KHN0cl9jKCJhID0gIiwgYSwgIiwgYiA9ICIsIGIsICIsIG1lYW4gPSAiLCBtZWFuLCAiLCB2YXJpYW5jZSA9ICIsIHZhcmlhbmNlKSkKCnVuaWYgPC0gdGliYmxlKHggPSByYW5nZSwgZCA9IDEvKGItYSksIHAgPSAoeC1hKS8oYi1hKSkKdW5pZgpnZ3Bsb3QodW5pZikgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdCh1bmlmKSArIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBkKSkKYGBgCiMjI1NhbXBsZQpgYGB7cn0KeCA8LSBydW5pZigxMCwgYSwgYikKYGBgCiMjRVhQT05FTlRJQUwKIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQojRm9yIGEgUG9pc3NvbiBwcm9jZXNzIHdpbiB3aGljaCBldmVudHMgb2NjdXIgYXQgcmFuZG9tIGF0IHJhdGUgbCwgdGhlIHdhaXRpbmcgdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgZXZlbnRzIGhhcyBhbiBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gd2l0aCBwYXJhbWV0ZXIgbAojUGFyYW1ldGVycwpsIDwtIDEvMjYgI3JhdGUKcmFuZ2UgPC0gc2VxKDAuMDAwMSwgMTAwLCAxMDAvMTAwMCkgIyBYID4gMCwgdW5ib3VuZGVkIHRvIHRoZSByaWdodApzdHJfYygibGFtYmRhID0gIiwgbCkKCiNwLmQuZi4KZGUgPC0gZnVuY3Rpb24oeCwgbCl7CiAgICAgIGwqZXhwKDEpXigtbCp4KSAjZGVjcmVhc2luZyBwLmQuZi4gIAp9CgojYy5kLmYuCnBlIDwtIGZ1bmN0aW9uKHgsIGwpewogICAgICAgIHAgPSAxLWV4cCgxKV4oLWwqeCkKfQoKZXhwb25lbnRpYWwgPC0gdGliYmxlKHggPSByYW5nZSwgCiAgICAgICAgICAgICAgICBkID0gZGUoeCwgbCksCiAgICAgICAgICAgICAgICBwID0gcGUoeCwgbCkpCmV4cG9uZW50aWFsCmdncGxvdChleHBvbmVudGlhbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChleHBvbmVudGlhbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyMjMi4gRXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojTXUsIHNpZ21hCm11IDwtIDEvbApzaWdtYV9zcXVhcmVkIDwtIDEvbF4yCnNpZ21hIDwtIHNxcnQoc2lnbWFfc3F1YXJlZCkgI211ID0gc2lnbWEKCnN0cl9jKCJtdSA9ICIsIG11LCAiLCBzaWdtYV9zcXVhcmVkID0gIiwgc2lnbWFfc3F1YXJlZCwgIiwgc2lnbWEgPSAiLCBzaWdtYSkKYGBgCgojIyNTYW1wbGUKYGBge3J9CnggPC0gcmV4cCgxMCwgbCkKYGBgCiMjIyNhLiBFc3RpbWF0ZXMKYGBge3J9CnNhbXBsZV9tZWFuIDwtIG1lYW4oeCkKbF9oYXQgPSAxL3NhbXBsZV9tZWFuICNiaWFzZWQKYGBgCiMjIyNiLiBMaWtlbGhvb2QKYGBge3J9CnRoZXRhIDwtIHNlcSgwLDMqbCwgMypsLzEwMDApCgpzdHJfYygnc2FtcGxlX21lYW4gPSAnLCByb3VuZChzYW1wbGVfbWVhbiwyKSwgIiwgbF9oYXQgPSAiLCByb3VuZChsX2hhdCwyKSkKCmxlIDwtIGZ1bmN0aW9uKHgsIHRoZXRhKXsKICAgICAgICBuIDwtIGxlbmd0aCh4KQogICAgICAgIHNhbXBsZV9tZWFuIDwtIG1lYW4oeCkKICAgICAgICAodGhldGFebikqZXhwKDEpXigtdGhldGEqbipzYW1wbGVfbWVhbikKfQpleHBvbmVudGlhbF9tbGUgPC0gdGliYmxlKHRoZXRhID0gdGhldGEsIG0gPSBsZSh4LCB0aGV0YSkpCmdncGxvdChleHBvbmVudGlhbF9tbGUpICsgZ2VvbV9saW5lKGFlcyh4ID0gdGhldGEsIHkgPSBtKSkKYGBgCiMjTk9STUFMCiMjI1BvcHVsYXRpb24gCiMjIyMxLiBNb2RlbApgYGB7cn0KI1BhcmFtZXRlcnMKbXUgPC0gNwpzaWdtYV9zcXVhcmVkIDwtIDEwMApzaWdtYSA8LSBzcXJ0KHNpZ21hX3NxdWFyZWQpCnN0cl9jKCJtdSA9ICIsIG11LCAiLCBzaWdtYV9zcXVhcmVkID0gIiwgc2lnbWFfc3F1YXJlZCwgIiwgc2lnbWEgPSAiLCBzaWdtYSkKCm11XzIgPC0gOQoKI1JhbmdlCnJhbmdlIDwtIHNlcShtdS00KnNpZ21hLCBtdSs0KnNpZ21hLCBzaWdtYS8xMikgI3VuYm91bmRlZCAKCiNwLmQuZi4KZG4gPC0gZnVuY3Rpb24oeCwgbXUsIHNpZ21hKXsKICAgICAgICAoMS8oc2lnbWEqc3FydCgyKnBpKSkpKmV4cCgtMC41KigoeC1tdSkvc2lnbWEpXjIpCn0Kbm9ybWFsIDwtIHRpYmJsZSh4ID0gcmFuZ2UsCiAgICAgICAgICAgICAgICAgZCA9IGRuKHgsIG11LCBzaWdtYSksICNzeW1tZXRyaWMgYWJvdXQgbWVhbgogICAgICAgICAgICAgICAgIHAgPSBwbm9ybSh4LCBtdSwgc2lnbWEpKQpub3JtYWwKZ2dwbG90KG5vcm1hbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChub3JtYWwpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKIyMjIzIuIEV4cGVjdGVkIHZhbHVlcwpgYGB7cn0Kc3RyX2MoIm11ID0gIiwgbXUsICIsIHNpZ21hX3NxdWFyZWQgPSAiLCBzaWdtYV9zcXVhcmVkLCAiLCBzaWdtYSA9ICIsIHJvdW5kKHNpZ21hLDMpKQpgYGAKIyMjIzMuIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIHNhbXBsZSBtZWFuLCBleHBlY3RlZCB2YWx1ZXMKYGBge3J9Cm4gPC0gMjAKCmV4cF9YX2JhciA8LSBtdQp2YXJfWF9iYXIgPC0gc2lnbWFfc3F1YXJlZC9uCnNkX1hfYmFyIDwtIHNpZ21hL3NxcnQobikKc3RyX2MoIm4gPSAiLCBuLCAiLCBleHBfWF9iYXIgPSAiLCByb3VuZChleHBfWF9iYXIsMyksICIsIHZhcl9YX2JhciA9ICIsIHJvdW5kKHZhcl9YX2JhciwzKSwgIiwgc2RfWF9iYXIgPSAiLCByb3VuZChzZF9YX2JhciwzKSkKYGBgCiMjIyM0LiBTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSB2YXJpYW5jZSwgZXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQpleHBfU19zcXVhcmVkIDwtIHNpZ21hX3NxdWFyZWQKZXhwX1MgPC0gc2lnbWEKc3RyX2MoImV4cF9TX3NxdWFyZWQgPSAiLCByb3VuZChleHBfU19zcXVhcmVkLDMpLCAiLCBleHBfUyA9ICIsIHJvdW5kKGV4cF9TLDMpKQpgYGAKCiMjI1NhbXBsZQpgYGB7cn0KeCA8LSBybm9ybShuLCBtdSwgc2lnbWEpCgpuXzIgPC0gMzAKeF8yIDwtIHJub3JtKG4sIG11XzIsIHNpZ21hKQojIHggPC0gYygtNiwxLDIsNCwyNCwyNywzMykKIyBuIDwtIGxlbmd0aCh4KQpgYGAKIyMjI2EuIEVzdGltYXRlcwpgYGB7cn0Kc2FtcGxlX21lYW4gPC0gbWVhbih4KSAjbXVfaGF0CgpzYW1wbGVfdmFyIDwtIHZhcih4KSAjc19zcXVhcmVkCnNhbXBsZV9zZCA8LSBzcXJ0KHNhbXBsZV92YXIpICNzCgpzYW1wbGVfbWVhbl8yIDwtIG1lYW4oeF8yKQpzYW1wbGVfdmFyXzIgPC0gdmFyKHhfMikKc2FtcGxlX3Zhcl9wb29sZWQgPC0gKChuLTEpKnNhbXBsZV92YXIrKG5fMi0xKSpzYW1wbGVfdmFyXzIpLyhuK25fMi0yKQpzYW1wbGVfc2RfcG9vbGVkIDwtIHNxcnQoc2FtcGxlX3Zhcl9wb29sZWQpCnNhbXBsZV9tZWFuX2RpZmYgPC0gc2FtcGxlX21lYW4tc2FtcGxlX21lYW5fMgoKIyBzaWdtYV9zcXVhcmVkX2hhdCA8LSBzdW0oKHgtbWVhbih4KSleMikvbGVuZ3RoKHgpICNiaWFzZWQKIyBzaWdtYV9oYXQgPC0gc3FydChzdW0oKHgtbWVhbih4KSleMikvbGVuZ3RoKHgpKSAjYmlhc2VkCgplc3RfdmFyX1hfYmFyIDwtIHNhbXBsZV92YXIvbiAjZXN0aW1hdGUgc2lnbWFfc3F1YXJlZCB3aXRoIHNhbXBsZV92YXIKZXN0X3NkX1hfYmFyIDwtIHNhbXBsZV9zZC9zcXJ0KG4pICNlc3RpbWF0ZSBzaWdtYSB3aXRoIHNhbXBsZV9zZAoKc3RyX2MoInNhbXBsZV9tZWFuID0gIiwgcm91bmQoc2FtcGxlX21lYW4sMyksICIsIHNhbXBsZV92YXIgPSAiLCByb3VuZChzYW1wbGVfdmFyLDMpLCAiLCBzYW1wbGVfc2QgPSAiLCByb3VuZChzYW1wbGVfc2QsMyksICIsIGVzdF92YXJfWF9iYXIgPSAiLCByb3VuZChlc3RfdmFyX1hfYmFyLDMpLCAiLCBlc3Rfc2RfWF9iYXIgPSAiLCByb3VuZChlc3Rfc2RfWF9iYXIsMykpCmBgYAojIyMjYy4gQ29uZmlkZW5jZSBpbnRlcnZhbApgYGB7cn0KYWxwaGEgPC0gMC4wNQpzdHJfYygiYWxwaGEgPSAiLCBhbHBoYSkKCiNDb25maWRlbmNlIGludGVydmFsCkNJIDwtIGMoc2FtcGxlX21lYW4gLSBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2JhciwgCiAgICAgICAgc2FtcGxlX21lYW4gKyBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2JhcikKc3RyX2MoIkNJID0gIiwgcGFzdGUocm91bmQoQ0ksMyksIGNvbGxhcHNlID0gIiwgIikpCmBgYAojIyMjZC4gSHlwb3RoZXNpcyB0ZXN0CmBgYHtyfQptdV8wID0gNwpjcml0aWNhbF92YWx1ZXMgPC0gYyhtdV8wIC0gcW5vcm0oMS1hbHBoYS8yKSplc3Rfc2RfWF9iYXIsCiAgICAgICAgICAgICAgICAgICAgIG11XzAgKyBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2JhcikKeiA8LSAoc2FtcGxlX21lYW4tbXVfMCkvZXN0X3NkX1hfYmFyICN3aGVuIEhfMCBpcyB0cnVlLCBaIH4gTigwLDEpCnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHFub3JtKGFscGhhLzIpLCBxbm9ybSgxLWFscGhhLzIpKQpwX3ZhbHVlIDwtIDIqKDEtcG5vcm0oYWJzKHopKSkKCnN0cl9jKCJIMDogbXVfMCA9ICIsIG11XzApCnN0cl9jKCJjcml0aWNhbCB2YWx1ZXMgPSAiLCBwYXN0ZShyb3VuZChjcml0aWNhbF92YWx1ZXMsMyksY29sbGFwc2UgPSAiLCAiKSkKc3RyX2MoInNhbXBsZV9tZWFuID0gIiwgcm91bmQoc2FtcGxlX21lYW4sMykpCnN0cl9jKCJzdGFuZGFyZCBjcml0aWNhbCB2YWx1ZXMgPSAiLCBwYXN0ZShyb3VuZChzdGFuZGFyZF9jcml0aWNhbF92YWx1ZXMsMyksY29sbGFwc2UgPSAiLCAiKSkKc3RyX2MoInogPSAiLCByb3VuZCh6LCAzKSkKc3RyX2MoInBfdmFsdWUgPSAiLCByb3VuZChwX3ZhbHVlLCA1KSkKCnoudGVzdCh4LCBtdSA9IG11XzAsIHNpZ21hLnggPSBzYW1wbGVfc2QpCmBgYAojIyMjZS4gUG93ZXIgYW5kIHNhbXBsZSBzaXplCmBgYHtyfQojV2hlbiBIXzEgaXMgdHJ1ZSwgbXUgPSBtdV8wICsgZCwgWiAtIGQvc2RfWF9iYXIgfiBOKDAsMSkKZCA8LSAgMgpzaWdtYSA8LSA1Cm4gPC0gMzAKc2RfWF9iYXIgPC0gc2lnbWEvc3FydChuKQphbHBoYSA8LSAwLjA1CmRfeiA8LSBkL3NkX1hfYmFyCnBvd2VyIDwtIDEgLSBwbm9ybShxbm9ybSgxLWFscGhhLzIpIC0gZF96KQpzdHJfYygiZCA9ICIsIGQsICIsIGRfeiA9ICIsIHJvdW5kKGRfeiwzKSwgICIsIHBvd2VyID0gIiwgcm91bmQocG93ZXIsNCkpCmBgYAojIyMjZi4gU2FtcGxlIHNpemUKYGBge3J9CmdhbW1hIDwtIDAuOQpzYW1wbGVfc2l6ZSA8LSAoc2lnbWFfc3F1YXJlZC9kXjIpKihxbm9ybSgxLWFscGhhLzIpIC0gcW5vcm0oMS1nYW1tYSkpXjIKCnN0cl9jKCJkID0gIiwgZCwgICIsIGdhbW1hID0gIiwgZ2FtbWEsICIsIHNhbXBsZSBzaXplID0gIiwgY2VpbGluZyhzYW1wbGVfc2l6ZSkpCmBgYAoKIyNTVFVERU5UJ1MgVAojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9Cm51IDwtIG4tMQpyYW5nZSA8LSBzZXEoLTQsIDQsIDAuMDgpICN1bmJvdW5kZWQgCnByaW50KHN0cl9jKCJkZiA9ICIsIG51KSkKcnQoMTAsIG51KQp0IDwtIHRpYmJsZSh4ID0gcmFuZ2UsIAogICAgICAgICAgICAgICAgZCA9IGR0KHgsIG51KSwKICAgICAgICAgICAgICAgIHAgPSBwdCh4LCBudSkpCnQKZ2dwbG90KHQpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHApKQpnZ3Bsb3QodCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyNTYW1wbGUKVXNlIG5vcm1hbAoKIyMjI2MuaS4gQ29uZmlkZW5jZSBpbnRlcnZhbApgYGB7cn0KYWxwaGEgPC0gMC4wNQpzdHJfYygiYWxwaGEgPSAiLCBhbHBoYSkKCiNDb25maWRlbmNlIGludGVydmFsCkNJIDwtIGMoc2FtcGxlX21lYW4gLSBxdCgxLWFscGhhLzIsIG51KSplc3Rfc2RfWF9iYXIsIAogICAgICAgIHNhbXBsZV9tZWFuICsgcXQoMS1hbHBoYS8yLCBudSkqZXN0X3NkX1hfYmFyKQpzdHJfYygiQ0kgPSAiLCBwYXN0ZShyb3VuZChDSSw2KSwgY29sbGFwc2UgPSAiLCAiKSkKYGBgCiMjIyNjLmlpIENvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGRpZmZlcmVuY2Ugb2YgbWVhbnMKYGBge3J9Cm51XzIgPC0gbiArIG5fMiAtIDIKCkNJIDwtIGMoc2FtcGxlX21lYW5fZGlmZiAtIHF0KDEtYWxwaGEvMiwgbnVfMikqc2FtcGxlX3NkX3Bvb2xlZCpzcXJ0KDEvbisxL25fMiksIAogICAgICAgIHNhbXBsZV9tZWFuX2RpZmYgKyBxdCgxLWFscGhhLzIsIG51XzIpKnNhbXBsZV9zZF9wb29sZWQqc3FydCgxL24rMS9uXzIpKQoKc3RyX2MoIkNJID0gIiwgcGFzdGUocm91bmQoQ0ksNiksIGNvbGxhcHNlID0gIiwgIikpCmBgYAoKIyMjI2QuIEh5cG90aGVzaXMgdGVzdApgYGB7cn0KbXVfMCA9IDAKY3JpdGljYWxfdmFsdWVzIDwtIGMobXVfMCAtIHF0KDEtYWxwaGEvMiwgbnUpKmVzdF9zZF9YX2JhciwKICAgICAgICAgICAgICAgICAgICAgbXVfMCArIHF0KDEtYWxwaGEvMiwgbnUpKmVzdF9zZF9YX2JhcikKdCA8LSAoc2FtcGxlX21lYW4tbXVfMCkvZXN0X3NkX1hfYmFyCnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHF0KGFscGhhLzIsIG51KSwgcXQoMS1hbHBoYS8yLCBudSkpCgpwX3ZhbHVlIDwtIDIqKDEtcHQoYWJzKHQpLCBudSkpCnN0cl9jKCJIMDogbXVfMCA9ICIsIG11XzApCnN0cl9jKCJkZiA9ICIsIGxlbmd0aCh4KS0xKQpzdHJfYygiY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJzYW1wbGVfbWVhbiA9ICIsIHJvdW5kKHNhbXBsZV9tZWFuLDMpKQpzdHJfYygic3RhbmRhcmQgY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoc3RhbmRhcmRfY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJ0ID0gIiwgcm91bmQodCwgNCkpCnN0cl9jKCJwX3ZhbHVlID0gIiwgcm91bmQocF92YWx1ZSwgNSkpCgp0LnRlc3QoeCwgbXUgPSBtdV8wLCBzaWdtYS54ID0gc2FtcGxlX3NkKQpgYGAKCiMjQ0hJLVNRVUFSRUQKYGBge3J9CnIgPC0gNgpyYW5nZSA8LSBzZXEoMC4wMDAxLCA1KnIsIHIvMjApICN4ID4gMApwcmludChzdHJfYygiZGVncmVlcyBvZiBmcmVlZG9tID0gIiwgciwgIiwgbWVhbiA9ICIsIHIsICIsIHZhcmlhbmNlID0gIiwgMipyKSkKcmNoaXNxKDEwLCByKQpjaGlzcSA8LSB0aWJibGUoeCA9IHJhbmdlLCAKICAgICAgICAgICAgICAgIGQgPSBkY2hpc3EoeCwgciksCiAgICAgICAgICAgICAgICBwID0gcGNoaXNxKHgsIHIpKQpjaGlzcQpnZ3Bsb3QoY2hpc3EpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHApKQpnZ3Bsb3QoY2hpc3EpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKIyMjR29vZG5lc3Mgb2YgZml0CiMjIyNkaXNjcmV0ZSB1bmlmb3JtCmBgYHtyfQptXyA8LSAxCm4gPC0gNwpPIDwtIGMoMTcsMTAsMTIsMTUsNSw0LDgpCm4gPC0gc3VtKE8pCnggPC0gMTpsZW5ndGgoTykKbSA8LSAxLyhuLW1fKzEpCmdvZiA8LSB0aWJibGUoeCA9IHgsCiAgICAgICAgICAgICAgICBtID0gbSwKICAgICAgICAgICAgICAgIE8gPSBPLCAKICAgICAgICAgICAgICAgIEUgPSBtKm4sCiAgICAgICAgICAgICAgICAnKE8tRSleMi9FJyA9IChPLUUpXjIvRSkKZ29mCngyIDwtIHN1bShnb2YkYChPLUUpXjIvRWApCm5fcGFyYW1ldGVycyA8LSAwCnIgPC0gbnJvdyhnb2YpIC0gbl9wYXJhbWV0ZXJzIC0gMSAjayAtIHAgLSAxCnN0cl9jKCJuID0gIiwgbiwgIiwgY2hpX3NxdWFyZSA9ICIsIHJvdW5kKHgyLDMpLCAiLCBwID0gIiwgcm91bmQoMS1wY2hpc3EoeDIsIHIpLDMpKQpgYGAKIyMjI2dlb21ldHJpYwpgYGB7cn0KcF9oYXQgPC0gMC42NTcKTyA8LSBjKDcxLDI4LDEwKQpuIDwtIHN1bShPKQp4IDwtIDE6KGxlbmd0aChPKS0xKQp5IDwtIHN0cl9jKCLiiaUiLCAobGVuZ3RoKE8pKSkKbSA8LSBjKGRnKHgsIHBfaGF0KSwxLXBnKG1heCh4KSwgcF9oYXQpKQpnb2YgPC0gdGliYmxlKHggPSBjKHgseSksCiAgICAgICAgICAgICAgICBtID0gbSwKICAgICAgICAgICAgICAgIE8gPSBPLCAKICAgICAgICAgICAgICAgIEUgPSBtKm4sCiAgICAgICAgICAgICAgICAnKE8tRSleMi9FJyA9IChPLUUpXjIvRSkKZ29mCngyIDwtIHN1bShnb2YkYChPLUUpXjIvRWApCm5fcGFyYW1ldGVycyA8LSAxCnIgPC0gbnJvdyhnb2YpIC0gbl9wYXJhbWV0ZXJzIC0gMSAjayAtIHAgLSAxCnN0cl9jKCJuID0gIiwgbiwgIiwgcF9oYXQgPSAiLCBwX2hhdCwgIiwgZGYgPSAiLCByLCAiICwgY2hpX3NxdWFyZSA9ICIsIHJvdW5kKHgyLDMpLCAiLCBwID0gIiwgcm91bmQoMS1wY2hpc3EoeDIsIHIpLDMpKQpgYGAKIyMjI1BvaXNzb24KYGBge3J9CmxfaGF0IDwtIDAuNwpPIDwtIGMoMTQ0LDkxLDMyLDEzKQpuIDwtIHN1bShPKQp4IDwtIDA6KGxlbmd0aChPKS0yKQp5IDwtIHN0cl9jKCLiiaUiLCAobGVuZ3RoKE8pLTEpKQptIDwtIGMoZHBvaXMoeCwgbF9oYXQpLDEtcHBvaXMobWF4KHgpLCBsX2hhdCkpCmdvZiA8LSB0aWJibGUoeCA9IGMoeCx5KSwKICAgICAgICAgICAgICAgIG0gPSBtLAogICAgICAgICAgICAgICAgTyA9IE8sIAogICAgICAgICAgICAgICAgRSA9IG0qbiwKICAgICAgICAgICAgICAgICcoTy1FKV4yL0UnID0gKE8tRSleMi9FKQpnb2YKeDIgPC0gc3VtKGdvZiRgKE8tRSleMi9FYCkKCm5fcGFyYW1ldGVycyA8LSAxICNlc3RpbWF0ZWQgZnJvbSBkYXRhCnIgPC0gbnJvdyhnb2YpIC0gbl9wYXJhbWV0ZXJzIC0gMSAjayAtIHAgLSAxCgpzdHJfYygibiA9ICIsIG4sICIsIGxfaGF0ID0gIiwgbF9oYXQsICIsIGRmID0gIiwgciwgIiwgY2hpX3NxdWFyZSA9ICIsIHJvdW5kKHgyLDMpLCAiLCBwID0gIiwgcm91bmQoMS1wY2hpc3EoeDIsIHIpLDMpKQpgYGAKCiMjUkVHUkVTU0lPTgojIyNQb3B1bGF0aW9uCmBgYHtyfQojUGFyYW1ldGVycwpzaWdtYV9zcXVhcmVkIDwtIDE1MApzaWdtYSA8LSBzcXJ0KHNpZ21hX3NxdWFyZWQpCmFscGhhXyA8LSA1CmJldGEgPC0gNAp4IDwtIHNlcSgtNSwyMCwwLjI1KQoKaCA8LSBmdW5jdGlvbih4LCBhbHBoYV8sIGJldGEpewogICAgICAgIGFscGhhXyArIGJldGEqeAp9CiNwLmQuZi4KcmVncmVzc2lvbl9tb2RlbCA8LSB0aWJibGUoeCA9IHgsCiAgICAgICAgICAgICAgICAgcV8wLjAyNSA9IHFub3JtKDAuMDI1LCBoKHgsIGFscGhhXywgYmV0YSksIHNpZ21hKSwKICAgICAgICAgICAgICAgICBxXzAuNSA9IHFub3JtKDAuNSwgaCh4LCBhbHBoYV8sIGJldGEpLCBzaWdtYSksCiAgICAgICAgICAgICAgICAgcV8wLjk3NSA9IHFub3JtKDAuOTc1LCBoKHgsIGFscGhhXywgYmV0YSksIHNpZ21hKQogICAgICAgICAgICAgICAgICkgJT4lCiAgICAgICAgZ2F0aGVyKGtleSA9IHF1YW50aWxlLCB2YWx1ZSA9IHosIC14KQoKcmVncmVzc2lvbl9tb2RlbApnZ3Bsb3QocmVncmVzc2lvbl9tb2RlbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0geiwgY29sID0gcXVhbnRpbGUpKQpgYGAKIyMjI1NhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZXN0aW1hdG9ycywgZXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQpuIDwtIDUwCgpleHBfYWxwaGFfaGF0IDwtIGFscGhhCmV4cF9iZXRhX2hhdCA8LSBiZXRhCmBgYAojIyNTYW1wbGUKYGBge3J9CnJlZ3Jlc3Npb25fc2FtcGxlIDwtIHRpYmJsZSh4ID0gcnVuaWYobiwgbWluKHgpLCBtYXgoeCkpLAogICAgICAgICAgICAgICAgICAgICB5ID0gcm5vcm0oeCwgaCh4LCBhbHBoYV8sIGJldGEpLCBzaWdtYSkpCgpnZ3Bsb3QocmVncmVzc2lvbl9zYW1wbGUpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSB5KSkgKyBleHBhbmRfbGltaXRzKHggPSAwLCB5ID0gMCkKYGBgCiMjIyNhLiBFc3RpbWF0ZXMKYGBge3J9CnggPC0gcmVncmVzc2lvbl9zYW1wbGUkeAp4X2JhciA8LSBtZWFuKHgpCnkgPC0gcmVncmVzc2lvbl9zYW1wbGUkeQoKU194eCA8LSBzdW0oKHgtbWVhbih4KSleMikKU195eSA8LSBzdW0oKHktbWVhbih5KSleMikKU194eSA8LSBzdW0oKHgtbWVhbih4KSkqKHktbWVhbih5KSkpCgojTGVhc3Qgc3F1YXJlcyBlc3RpbWF0ZXMgb2YgcGFyYW1ldGVycwpiZXRhX2hhdCA8LSBTX3h5L1NfeHgKI2VzdF92YXJfYmV0YV9oYXQgPC0gc2lnbWFfc3F1YXJlZC9TX3h4CgphbHBoYV9oYXQgPC0gbWVhbih5KSAtIGJldGFfaGF0Km1lYW4oeCkKI2VzdF92YXJfYWxwaGFfaGF0IDwtIHhfYmFyXjIvU194eCsxL24KCiNCZXN0IGZpdApiZXN0X2ZpdCA8LSBmdW5jdGlvbih4LCBhbHBoYV9oYXQsIGJldGFfaGF0KXsKICAgICAgICBhbHBoYV9oYXQgKyBiZXRhX2hhdCp4Cn0KCnJlZ3Jlc3Npb25fc2FtcGxlIDwtIHJlZ3Jlc3Npb25fc2FtcGxlICU+JSAKICAgICAgICBtdXRhdGUoeV9oYXQgPSBiZXN0X2ZpdCh4LCBhbHBoYV9oYXQsIGJldGFfaGF0KSwKICAgICAgICAgICAgICAgcmVzaWR1YWwgPSB5LXlfaGF0ICkKCiNWYXJpYW5jZSBvZiByZXNpZHVhbHMKeV9oYXQgPC0gcmVncmVzc2lvbl9zYW1wbGUkeV9oYXQKc3VtX3NxdWFyZWRfZGlmZl95X2hhdCA8LSBzdW0oKHkteV9oYXQpXjIpCgpzX3NxdWFyZWQgPC0gc3VtX3NxdWFyZWRfZGlmZl95X2hhdC8obi0yKSAjdW5iaWFzZWQgZXN0aW1hdG9yIG9mIHNpZ21hX3NxdWFyZWQsIHRoZSB2YXJpYW5jZSBvZiB0aGUgcmFuZG9tIHRlcm1zCnMgPC0gc3FydChzX3NxdWFyZWQpCgplc3Rfc2RfYmV0YV9oYXQgPC0gcy9zcXJ0KFNfeHgpCgpnZ3Bsb3QocmVncmVzc2lvbl9zYW1wbGUpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSB5KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0geV9oYXQpKQpgYGAKIyMjI2MuaS4gQ29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgYmV0YQpgYGB7cn0KYWxwaGEgPC0gMC4wNQoKQ0lfYmV0YSA8LSBjKAogICAgICAgIGJldGFfaGF0IC0gcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9iZXRhX2hhdCwgCiAgICAgICAgYmV0YV9oYXQgKyBxdCgxLWFscGhhLzIsIG4tMikqZXN0X3NkX2JldGFfaGF0KQoKc3RyX2MoImJldGFfaGF0ID0gIiwgcm91bmQoYmV0YV9oYXQsMyksICIsIENJX2JldGEgPSAiLCBwYXN0ZShyb3VuZChDSV9iZXRhLDMpLCBjb2xsYXBzZSA9ICIsICIpKQpgYGAKIyMjI2MuaWkuIENvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIG1lYW4gcmVzcG9uc2UKYGBge3J9CmVzdF9zZF9ZX2JhciA8LSBmdW5jdGlvbih4LCBzLCB4X2JhciwgU194eCwgbil7CiAgICAgICAgcypzcXJ0KCh4LXhfYmFyKV4yL1NfeHggKyAxL24pCn0KICAgICAgICAKcmVncmVzc2lvbl9zYW1wbGUgPC0gcmVncmVzc2lvbl9zYW1wbGUgJT4lIAogbXV0YXRlKENJX2xvdyA9IHlfaGF0IC0gcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9ZX2Jhcih4LCBzLCB4X2JhciwgU194eCwgbiksCiAgICAgICAgQ0lfaGlnaCA9IHlfaGF0ICsgcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9ZX2Jhcih4LCBzLCB4X2JhciwgU194eCwgbikpCgpnZ3Bsb3QocmVncmVzc2lvbl9zYW1wbGUpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSB5KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0geV9oYXQpKSArIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBDSV9sb3cpKSArIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBDSV9oaWdoKSkKYGBgCgojIyMjYy5paWkuIFByZWRpY3Rpb24gaW50ZXJ2YWwKYGBge3J9CmVzdF9zZF9ZIDwtIGZ1bmN0aW9uKHgsIHMsIHhfYmFyLCBTX3h4LCBuKXsKICAgICAgICBzKnNxcnQoKHgteF9iYXIpXjIvU194eCArIDEvbiArIDEpCn0KICAgICAgICAKcmVncmVzc2lvbl9zYW1wbGUgPC0gcmVncmVzc2lvbl9zYW1wbGUgJT4lIAogbXV0YXRlKENJX2xvdyA9IHlfaGF0IC0gcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9ZKHgsIHMsIHhfYmFyLCBTX3h4LCBuKSwKICAgICAgICBDSV9oaWdoID0geV9oYXQgKyBxdCgxLWFscGhhLzIsIG4tMikqZXN0X3NkX1koeCwgcywgeF9iYXIsIFNfeHgsIG4pKQoKZ2dwbG90KHJlZ3Jlc3Npb25fc2FtcGxlKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0geSkpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHlfaGF0KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gQ0lfbG93KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gQ0lfaGlnaCkpCmBgYAojIyMjZC4gSHlwb3RoZXNpcyB0ZXN0IGZvciBiZXRhCmBgYHtyfQpiZXRhXzAgPSAwCmNyaXRpY2FsX3ZhbHVlcyA8LSBjKGJldGFfMCAtIHF0KDEtYWxwaGEvMiwgbi0yKSplc3Rfc2RfYmV0YV9oYXQsCiAgICAgICAgICAgICAgICAgICAgIGJldGFfMCArIHF0KDEtYWxwaGEvMiwgbi0yKSplc3Rfc2RfYmV0YV9oYXQpCnQgPC0gKGJldGFfaGF0LWJldGFfMCkvZXN0X3NkX2JldGFfaGF0CnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHF0KGFscGhhLzIsIG4tMiksIHF0KDEtYWxwaGEvMiwgbi0yKSkKCnBfdmFsdWUgPC0gMiooMS1wdChhYnModCksIG4tMikpCmBgYAoKIyNOT04tUEFSQU1FVFJJQwojIyNXaWxrb3hvbiBzaWduZWQgcmFuawpgYGB7cn0KI1NpbmdsZSBzYW1wbGUKeCA8LSBjKDE5LCAzNSwgMzYsIDI4LCAzNywgMTAsIDI1LCAzNCwgMzAsIDM5KQptXzAgPSAzNSAjc2V0IGh5cG90aGVzaXplZCBtZWRpYW4KZF8gPC0geC1tXzAgI2NhbGN1bGF0ZSBkaWZmZXJlbmNlCgojc2V0IG9mIHBhaXJlZCBkaWZmZXJlbmNlcwp4MSA8LSBjKDE3MSwgNzI5LCA2NzksIDQzMSwgMzAwLCAzMTAsIDc5NCwgOTcwLCAzODgpCngyIDwtIGMoMTk4LCA3MzQsIDc3OSwgNzc2LCAzMDAsIDc1MCwgNjk3LCAzNjgsIDQ4OCkKZF8gPC0geDEteDIKCmQgPC0gZF9bZF8hPTBdICNyZW1vdmUgemVyb3MKcmFuayA8LSByYW5rKGFicyhkKSkgI2ZpbmQgdGhlIHJhbmsgb2YgYWJzb2x1dGUgdmFsdWVzCndfcGx1cyA8LSBzdW0ocmFua1tzaWduKGQpPT0xXSkgI3N1bSBvZiB0aGUgcmFua3Mgb2YgcG9zaXRpdmUgZGlmZmVyZW5jZXMKd19wbHVzCndpbGNveC50ZXN0KGQpCmBgYApOb3JtYWwgYXBwcm94aW1hdGlvbgpgYGB7cn0KI25vcm1hbCBhcHByb3hpbWF0aW9uIHdoZW4gbiDiiaUgMTYKbiA8LSBsZW5ndGgoZCkKCmV4cF93X3BsdXMgPC0gKG4qKG4rMSkpLzQKdmFyX3dfcGx1cyA8LSAobioobisxKSooMipuKzEpKS8yNApzZF93X3BsdXMgPC0gc3FydCh2YXJfd19wbHVzKQoKYWxwaGEgPC0gMC4wNQpjcml0aWNhbF92YWx1ZXMgPC0gYyhtXzAgLSBxbm9ybSgxLWFscGhhLzIpKnNkX3dfcGx1cywKICAgICAgICAgICAgICAgICAgICAgbV8wICsgcW5vcm0oMS1hbHBoYS8yKSpzZF93X3BsdXMpCnogPC0gKHdfcGx1cyAtIGV4cF93X3BsdXMpL3NkX3dfcGx1cwpzdGFuZGFyZF9jcml0aWNhbF92YWx1ZXMgPC0gYyhxbm9ybShhbHBoYS8yKSwgcW5vcm0oMS1hbHBoYS8yKSkKcF92YWx1ZSA8LSAyKigxLXBub3JtKGFicyh6KSkpCgpzdHJfYygibiA9ICIsIG4pCnN0cl9jKCJIMDogbV8wID0gIiwgbV8wKQpzdHJfYygiY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJleHBfd19wbHVzID0gIiwgZXhwX3dfcGx1cykKc3RyX2MoInN0YW5kYXJkIGNyaXRpY2FsIHZhbHVlcyA9ICIsIHBhc3RlKHJvdW5kKHN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcywzKSxjb2xsYXBzZSA9ICIsICIpKQpzdHJfYygieiA9ICIsIHJvdW5kKHosIDMpKQpzdHJfYygicF92YWx1ZSA9ICIsIHJvdW5kKHBfdmFsdWUsIDUpKQpgYGAKCiMjI01hbm4tV2hpdG5leQpgYGB7cn0KYSA9IGMoMTAxLDEwNCwxMDcsMTA3LDEyMSwxMjEsMTI0LDEzNCwxNDYpIApiID0gYyg5MSw5Myw5NywxMDAsMTAxLDEwMiwxMDcsMTE0LDExNSwxMjYsMTMxKQoKdV9hIDwtIHN1bShyYW5rKGMoYSxiKSlbMTpsZW5ndGgoYSldKQp1X2EKYGBgCgpOb3JtYWwgYXBwcm94aW1hdGlvbgpgYGB7cn0KI25vcm1hbCBhcHByb3hpbWF0aW9uIHdoZW4gZWFjaCBzYW1wbGUg4omlIDgKbl9hIDwtIGxlbmd0aChhKQpuX2IgPC0gbGVuZ3RoKGIpCgpleHBfdV9hIDwtIChuX2EqKG5fYStuX2IrMSkpLzIKdmFyX3VfYSA8LSAobl9hKm5fYioobl9hK25fYisxKSkvMTIKc2RfdV9hIDwtIHNxcnQodmFyX3VfYSkKCmFscGhhIDwtIDAuMDUKY3JpdGljYWxfdmFsdWVzIDwtIGMobV8wIC0gcW5vcm0oMS1hbHBoYS8yKSpzZF91X2EsCiAgICAgICAgICAgICAgICAgICAgIG1fMCArIHFub3JtKDEtYWxwaGEvMikqc2RfdV9hKQp6IDwtICh1X2EgLSBleHBfdV9hKS9zZF91X2EKc3RhbmRhcmRfY3JpdGljYWxfdmFsdWVzIDwtIGMocW5vcm0oYWxwaGEvMiksIHFub3JtKDEtYWxwaGEvMikpCnBfdmFsdWUgPC0gMiooMS1wbm9ybShhYnMoeikpKQoKc3RyX2MoIm5fYSA9ICIsIG5fYSwgIiwgbl9iID0gIiwgbl9iKQpzdHJfYygiSDA6IG1fMCA9ICIsIG1fMCkKc3RyX2MoImNyaXRpY2FsIHZhbHVlcyA9ICIsIHBhc3RlKHJvdW5kKGNyaXRpY2FsX3ZhbHVlcywzKSxjb2xsYXBzZSA9ICIsICIpKQpzdHJfYygiZXhwX3VfYSA9ICIsIGV4cF91X2EpCnN0cl9jKCJzdGFuZGFyZCBjcml0aWNhbCB2YWx1ZXMgPSAiLCBwYXN0ZShyb3VuZChzdGFuZGFyZF9jcml0aWNhbF92YWx1ZXMsMyksY29sbGFwc2UgPSAiLCAiKSkKc3RyX2MoInogPSAiLCByb3VuZCh6LCAzKSkKc3RyX2MoInBfdmFsdWUgPSAiLCByb3VuZChwX3ZhbHVlLCA1KSkKYGBgCiMjTk9URVMKIyNUbyBkbwpOb24tbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWxzIGFuZCB0cmFuc2Zvcm1hdGlvbnMKQ2hpLXNxdWFyZSBnb29kbmVzcyBvZiBmaXQgdGVzdCBmb3IgYmlub21pYWwKCiMjI05vcm1hbCBwcm9iYWJpbGl0eSBwbG90CmBgYHtyfQpPIDwtIGMoMzMsIDIsIDI0LCAyNywgNCwgMSwgLTYpCnggPC0gc29ydChPKQpuIDwtIGxlbmd0aCh4KQppIDwtIDE6bgpwIDwtIGkvKG4rMSkKeSA8LSBxbm9ybShwKQpxcGxvdCh4LHkpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkKCmBgYAojIyNDZW50cmFsIGxpbWl0IHRoZW9yZW0KYGBge3J9CiNuIDwtIDEwCm5fdHJpYWxzIDwtIDUwMAp4IDwtIGMoKQpmb3IgKGkgaW4gMTpuX3RyaWFscykgewogICAgICAgIHhbaV0gPC0gbWVhbihyYmVybm91bGxpKG5fdHJpYWxzLDAuMDAxKSkgICAgICAgIAp9CgojZ2dwbG90KCkgKyBzdGF0X3FxX2xpbmUoYWVzKHNhbXBsZSA9IHgpKSArIHN0YXRfcXEoYWVzKHNhbXBsZSA9IHgpKQpnZ3Bsb3QoKSArIGdlb21faGlzdG9ncmFtKGFlcyh4ID0geCksIGJpbndpZHRoID0gMC4wMDAwMikKYGBgCiMjI0xhZGRlciBvZiBwb3dlcnMKYGBge3J9CmRmIDwtIHRpYmJsZSh4ID0gcm5vcm0oMTAsIDEwMCwgMTApLCB5ID0geCArIHJub3JtKDEwLCAwLCAxKSkKZGYKZ2dwbG90KGRmKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0geSkpCmBgYAojIyNCaW5vbWlhbCB2cyBQb2lzc29uCmBgYHtyfQp4IDwtIGJpbm9tICU+JSBzZWxlY3QoeCwgQmlub21pYWwgPSBkKQp5IDwtIHBvaXNzb24gJT4lIHNlbGVjdCh4LCBQb2lzc29uID0gZCkgJT4lIGxlZnRfam9pbih4LCBieSA9ICJ4IikKeiA8LSB5ICU+JSBnYXRoZXIoa2V5LCB2YWx1ZSA9IGQsIC14KQpnZ3Bsb3QoeikgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IGQsIGNvbCA9IGtleSkpCmBgYAoKCiMjI1N0YXRpc3RpY2FsIHRhYmxlcwpgYGB7cn0KeCA8LSAwOjkvMTAwCnBoaV90YWJsZSA8LSB0aWJibGUoeiA9IHNlcSgwLDQsMC4xKSwgCiAgICAgICAnMCcgPSByb3VuZChwbm9ybSh6K3hbMV0pLDQpLAogICAgICAgJzEnID0gcm91bmQocG5vcm0oeit4WzJdKSw0KSwKICAgICAgICcyJyA9IHJvdW5kKHBub3JtKHoreFszXSksNCksCiAgICAgICAnMycgPSByb3VuZChwbm9ybSh6K3hbNF0pLDQpLAogICAgICAgJzQnID0gcm91bmQocG5vcm0oeit4WzVdKSw0KSwKICAgICAgICc1JyA9IHJvdW5kKHBub3JtKHoreFs2XSksNCksCiAgICAgICAnNicgPSByb3VuZChwbm9ybSh6K3hbN10pLDQpLAogICAgICAgJzcnID0gcm91bmQocG5vcm0oeit4WzhdKSw0KSwKICAgICAgICc4JyA9IHJvdW5kKHBub3JtKHoreFs5XSksNCksCiAgICAgICAnOScgPSByb3VuZChwbm9ybSh6K3hbMTBdKSw0KQogICAgICAgKQpwaGlfdGFibGUKYGBgCmBgYHtyfQpxel90YWJsZSA8LSB0aWJibGUoYSA9IHNlcSgwLjUsMC45OTksMC4wMSksIHFfYSA9IHJvdW5kKHFub3JtKGEpLDMpKQpxel90YWJsZQpgYGAKCmBgYHtyfQpxdF90YWJsZSA8LSB0aWJibGUoZGYgPSAxOjEwMCwgCiAgICAgICAgICAgICAgICAgICAnMC45MCcgPSByb3VuZChxdCgwLjksIGRmKSwzKSwKICAgICAgICAgICAgICAgICAgICcwLjk1JyA9IHJvdW5kKHF0KDAuOTUsIGRmKSwzKSwKICAgICAgICAgICAgICAgICAgICcwLjk3NScgPSByb3VuZChxdCgwLjk3NSwgZGYpLDMpLAogICAgICAgICAgICAgICAgICAgJzAuOTknID0gcm91bmQocXQoMC45OSwgZGYpLDMpLAogICAgICAgICAgICAgICAgICAgJzAuOTk1JyA9IHJvdW5kKHF0KDAuOTk1LCBkZiksMyksCiAgICAgICAgICAgICAgICAgICAnMC45OTknID0gcm91bmQocXQoMC45OTksIGRmKSwzKSkKcXRfdGFibGUKYGBgCgpgYGB7cn0KY2hpc3FfdGFibGUgPC0gdGliYmxlKGRmID0gMToxMDAsIAogICAgICAgICAgICAgICAgICAgJzAuMDA1JyA9IHJvdW5kKHFjaGlzcSgwLjAwNSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuMDEnID0gcm91bmQocWNoaXNxKDAuMDEsIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjAyNScgPSByb3VuZChxY2hpc3EoMC4wMjUsIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjA1JyA9IHJvdW5kKHFjaGlzcSgwLjA1LCBkZiksMiksCiAgICAgICAgICAgICAgICAgICAnMC4xJyA9IHJvdW5kKHFjaGlzcSgwLjEsIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjUnID0gcm91bmQocWNoaXNxKDAuNSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuOScgPSByb3VuZChxY2hpc3EoMC45LCBkZiksMiksCiAgICAgICAgICAgICAgICAgICAnMC45NScgPSByb3VuZChxY2hpc3EoMC45NSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuOTc1JyA9IHJvdW5kKHFjaGlzcSgwLjk3NSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuOTknID0gcm91bmQocWNoaXNxKDAuOTksIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjk5NScgPSByb3VuZChxY2hpc3EoMC45OTUsIGRmKSwyKSkKY2hpc3FfdGFibGUKYGBgCgpQb2lzc29uIHZzIGdlb21ldHJpYwpgYGB7cn0KcCA8LSAwLjcKbCA8LSAwLjUgI2dlbmVyYWxseSBzdGVlcGVyIHRoYW4gZ2VvbWV0cmljLCBnZXRzIGEgYnVtcCBhcyBhcHByb2FjaGVzIGwgPSAxCmRmIDwtIHRpYmJsZSh4ID0gMDo5LCBHZW9tZXRyaWMgPSByb3VuZChkZ2VvbSh4LCBwKSwgNCksIFBvaXNzb24gPSByb3VuZChkcG9pcyh4LCBsKSwgNCkpICU+JSBnYXRoZXIoa2V5LCB2YWx1ZSwgLXgpCmdncGxvdChkZikgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IHZhbHVlLCBjb2wgPSAga2V5KSkKYGBgCgpCaW5vbWlhbCBhbHRlcm5hdGl2ZSBNTEU/CmBgYHtyfQojIE1MRSBtdWx0aXBsZSBvYnNlcnZhdGlvbnMKIyB4IDwtIHJiaW5vbSgxMCwgbiwgcCkKIyB4CiMgdGhldGEgPC0gc2VxKDAsMSwwLjAwMSkKIyBtIDwtIE5VTEwKIyBmb3IoaSBpbiAxOmxlbmd0aCh0aGV0YSkpewojICAgICAgICAgbVtpXSA8LSAgcHJvZChkKHgsIG4sIHRoZXRhW2ldKSkKIyB9CiMgYmlub21fbWxlMiA8LSB0aWJibGUodGhldGEgPSB0aGV0YSwgbSA9IG0pCiMgTUxFMiA8LSBmaWx0ZXIoYmlub21fbWxlMiwgbSA9PSBtYXgobSkpJHRoZXRhCiMgcHJpbnQoc3RyX2MoIk1MRTIgPSAiLCBNTEUyKSkKIyBtZWFuKHJhbmQpL24KIyBnZ3Bsb3QoYmlub21fbWxlMikgKyBnZW9tX2xpbmUoYWVzKHggPSB0aGV0YSwgeSA9IG0pKQoKYGBgCgo=